]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jul 2026 11:14:50 +0000 (13:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jul 2026 11:14:50 +0000 (13:14 +0200)
added patches:
drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch
drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch
drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch
drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch
drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch
drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch
drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch
drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch
drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch
drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch
drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch
drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch
drm-xe-nvm-fix-writable-override-for-cri.patch
drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch
drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch

17 files changed:
queue-7.1/drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch [new file with mode: 0644]
queue-7.1/drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch [new file with mode: 0644]
queue-7.1/drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch [new file with mode: 0644]
queue-7.1/drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch [new file with mode: 0644]
queue-7.1/drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch [new file with mode: 0644]
queue-7.1/drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch [new file with mode: 0644]
queue-7.1/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch
queue-7.1/drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch [new file with mode: 0644]
queue-7.1/drm-xe-nvm-fix-writable-override-for-cri.patch [new file with mode: 0644]
queue-7.1/drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch [new file with mode: 0644]
queue-7.1/drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch [new file with mode: 0644]
queue-7.1/series

diff --git a/queue-7.1/drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch b/queue-7.1/drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch
new file mode 100644 (file)
index 0000000..a6a8670
--- /dev/null
@@ -0,0 +1,44 @@
+From bb52249fbbe948875155ccd45cd8d74bf4ae747b Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Thu, 21 May 2026 09:18:59 -0400
+Subject: drm/amdkfd: Check bounds in allocate_event_notification_slot
+
+From: David Francis <David.Francis@amd.com>
+
+commit bb52249fbbe948875155ccd45cd8d74bf4ae747b upstream.
+
+The valid event ids go from 0 to KFD_SIGNAL_EVENT_LIMIT
+
+allocate_event_notification_slot has an option to specify
+an event id to allocate at, used by CRIU. We weren't checking
+the bounds on that value.
+
+Check them.
+
+v2: Lower bounds check is unecessary because of idr_alloc
+already rejecting negative numbers. Upper bounds check should
+be KFD_SIGNAL_EVENT_LIMIT since the signal mode mappings might
+not yet exist
+
+Signed-off-by: David Francis <David.Francis@amd.com>
+Reviewed-by: David Yat Sin <david.yatsin@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 6853f1f6cbbeb3f53ebbbd7286536aeb2c5d5f50)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_events.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+@@ -107,6 +107,9 @@ static int allocate_event_notification_s
+       }
+       if (restore_id) {
++              if (*restore_id >= KFD_SIGNAL_EVENT_LIMIT)
++                      return -EINVAL;
++
+               id = idr_alloc(&p->event_idr, ev, *restore_id, *restore_id + 1,
+                               GFP_KERNEL);
+       } else {
diff --git a/queue-7.1/drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch b/queue-7.1/drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch
new file mode 100644 (file)
index 0000000..29e9774
--- /dev/null
@@ -0,0 +1,109 @@
+From 47ea05f246bebc81c7796f56265cffd812cf0601 Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Mon, 6 Jul 2026 10:19:04 -0400
+Subject: drm/amdkfd: Check bounds on CRIU restore queue type and mqd size
+
+From: David Francis <David.Francis@amd.com>
+
+commit 47ea05f246bebc81c7796f56265cffd812cf0601 upstream.
+
+We weren't checking whether the values provided in the private
+data in kfd CRIU restore were within bounds.
+
+For queue type, add a KFD_QUEUE_TYPE_MAX and ensure the provided
+type is less than it.
+
+For mqd_size, add new function mqd_size_from_queue_type and confirm
+that the provided mqd_size matches expectations.
+
+Reviewed-by: David Yat Sin <david.yatsin@amd.com>
+Signed-off-by: David Francis <David.Francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f19d8086f6644083c913d70bfdeee20e1b6f46a5)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c  |    6 ++++
+ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h  |    2 +
+ drivers/gpu/drm/amd/amdkfd/kfd_priv.h                  |    3 +-
+ drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c |   24 ++++++++++++-----
+ 4 files changed, 27 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -3649,6 +3649,12 @@ out:
+       dqm_unlock(dqm);
+       return r;
+ }
++
++size_t mqd_size_from_queue_type(struct device_queue_manager *dqm, enum kfd_queue_type type)
++{
++      return dqm->mqd_mgrs[get_mqd_type_from_queue_type(type)]->mqd_size;
++}
++
+ #if defined(CONFIG_DEBUG_FS)
+ static void seq_reg_dump(struct seq_file *m,
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+@@ -329,6 +329,8 @@ int debug_refresh_runlist(struct device_
+ bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
+                                struct qcm_process_device *qpd,
+                                int doorbell_off, u32 *queue_format);
++size_t mqd_size_from_queue_type(struct device_queue_manager *dqm,
++                              enum kfd_queue_type type);
+ static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
+ {
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+@@ -436,7 +436,8 @@ enum kfd_queue_type  {
+       KFD_QUEUE_TYPE_SDMA,
+       KFD_QUEUE_TYPE_HIQ,
+       KFD_QUEUE_TYPE_SDMA_XGMI,
+-      KFD_QUEUE_TYPE_SDMA_BY_ENG_ID
++      KFD_QUEUE_TYPE_SDMA_BY_ENG_ID,
++      KFD_QUEUE_TYPE_MAX,
+ };
+ enum kfd_queue_format {
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+@@ -1003,6 +1003,23 @@ int kfd_criu_restore_queue(struct kfd_pr
+               goto exit;
+       }
++      pdd = kfd_process_device_data_by_id(p, q_data->gpu_id);
++      if (!pdd) {
++              pr_err("Failed to get pdd\n");
++              ret = -EINVAL;
++              goto exit;
++      }
++
++      if (q_data->type >= KFD_QUEUE_TYPE_MAX) {
++              ret = -EINVAL;
++              goto exit;
++      }
++
++      if (q_data->mqd_size != mqd_size_from_queue_type(pdd->dev->dqm, q_data->type)) {
++              ret = -EINVAL;
++              goto exit;
++      }
++
+       *priv_data_offset += sizeof(*q_data);
+       q_extra_data_size = (uint64_t)q_data->ctl_stack_size + q_data->mqd_size;
+@@ -1025,13 +1042,6 @@ int kfd_criu_restore_queue(struct kfd_pr
+       *priv_data_offset += q_extra_data_size;
+-      pdd = kfd_process_device_data_by_id(p, q_data->gpu_id);
+-      if (!pdd) {
+-              pr_err("Failed to get pdd\n");
+-              ret = -EINVAL;
+-              goto exit;
+-      }
+-
+       /*
+        * data stored in this order:
+        * mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]...
diff --git a/queue-7.1/drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch b/queue-7.1/drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch
new file mode 100644 (file)
index 0000000..335d9bc
--- /dev/null
@@ -0,0 +1,117 @@
+From 426ffae6ecc7ec77d32bf8be065c21a1b881b084 Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <Yongqiang.Sun@amd.com>
+Date: Tue, 2 Jun 2026 09:47:19 -0400
+Subject: drm/amdkfd: clamp v9 CRIU control stack checkpoint copy to BO size
+
+From: Yongqiang Sun <Yongqiang.Sun@amd.com>
+
+commit 426ffae6ecc7ec77d32bf8be065c21a1b881b084 upstream.
+
+CRIU checkpoint copies the MQD control stack using cp_hqd_cntl_stack_size
+from hardware without bounding it to the allocated BO region. If the HW
+field is larger than the queue's control stack allocation, memcpy reads
+past the BO into adjacent GTT memory and can leak kernel data to userspace.
+
+Store the page-aligned control stack BO size in mqd_manager and clamp
+checkpoint copies and reported checkpoint sizes to
+min(cp_hqd_cntl_stack_size, mm->ctl_stack_size). Apply the same bound
+for multi-XCC v9.4.3 checkpoint layout.
+
+Signed-off-by: Yongqiang Sun <Yongqiang.Sun@amd.com>
+Reviewed-by: David Francis <David.Francis@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 6c2abd0ec09e86c6323010673766f76050e28aa3)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h    |    1 
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c |   25 +++++++++++++++++++++---
+ 2 files changed, 23 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+@@ -127,6 +127,7 @@ struct mqd_manager {
+       struct mutex    mqd_mutex;
+       struct kfd_node *dev;
+       uint32_t mqd_size;
++      uint32_t ctl_stack_size;
+ };
+ struct mqd_user_context_save_area_header {
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+@@ -27,6 +27,7 @@
+ #include <linux/uaccess.h>
+ #include "kfd_priv.h"
+ #include "kfd_mqd_manager.h"
++#include "kfd_topology.h"
+ #include "v9_structs.h"
+ #include "gc/gc_9_0_offset.h"
+ #include "gc/gc_9_0_sh_mask.h"
+@@ -400,8 +401,11 @@ static int get_wave_state(struct mqd_man
+ static int get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size)
+ {
+       struct v9_mqd *m = get_mqd(mqd);
++      u32 per_xcc_size;
+-      if (check_mul_overflow(m->cp_hqd_cntl_stack_size, NUM_XCC(mm->dev->xcc_mask), ctl_stack_size))
++      per_xcc_size = min_t(u32, m->cp_hqd_cntl_stack_size, mm->ctl_stack_size);
++
++      if (check_mul_overflow(per_xcc_size, NUM_XCC(mm->dev->xcc_mask), ctl_stack_size))
+               return -EINVAL;
+       return 0;
+@@ -410,13 +414,15 @@ static int get_checkpoint_info(struct mq
+ static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+ {
+       struct v9_mqd *m;
++      u32 ctl_stack_copy_size;
+       /* Control stack is located one page after MQD. */
+       void *ctl_stack = (void *)((uintptr_t)mqd + AMDGPU_GPU_PAGE_SIZE);
+       m = get_mqd(mqd);
++      ctl_stack_copy_size = min_t(u32, m->cp_hqd_cntl_stack_size, mm->ctl_stack_size);
+       memcpy(mqd_dst, m, sizeof(struct v9_mqd));
+-      memcpy(ctl_stack_dst, ctl_stack, m->cp_hqd_cntl_stack_size);
++      memcpy(ctl_stack_dst, ctl_stack, ctl_stack_copy_size);
+ }
+ static void checkpoint_mqd_v9_4_3(struct mqd_manager *mm,
+@@ -425,15 +431,19 @@ static void checkpoint_mqd_v9_4_3(struct
+                                                                 void *ctl_stack_dst)
+ {
+       struct v9_mqd *m;
++      u32 ctl_stack_stride;
+       int xcc;
+       uint64_t size = get_mqd(mqd)->cp_mqd_stride_size;
++      ctl_stack_stride = min_t(u32, get_mqd(mqd)->cp_hqd_cntl_stack_size,
++                               mm->ctl_stack_size);
++
+       for (xcc = 0; xcc < NUM_XCC(mm->dev->xcc_mask); xcc++) {
+               m = get_mqd(mqd + size * xcc);
+               checkpoint_mqd(mm, m,
+                               (uint8_t *)mqd_dst + sizeof(*m) * xcc,
+-                              (uint8_t *)ctl_stack_dst + m->cp_hqd_cntl_stack_size * xcc);
++                              (uint8_t *)ctl_stack_dst + ctl_stack_stride * xcc);
+       }
+ }
+@@ -987,6 +997,15 @@ struct mqd_manager *mqd_manager_init_v9(
+               mqd->is_occupied = kfd_is_occupied_cp;
+               mqd->get_checkpoint_info = get_checkpoint_info;
+               mqd->mqd_size = sizeof(struct v9_mqd);
++              if (dev->kfd->cwsr_enabled) {
++                      struct kfd_topology_device *topo_dev;
++
++                      topo_dev = kfd_topology_device_by_id(dev->id);
++                      if (topo_dev)
++                              mqd->ctl_stack_size =
++                                      ALIGN(topo_dev->node_props.ctl_stack_size,
++                                            AMDGPU_GPU_PAGE_SIZE);
++              }
+               mqd->mqd_stride = mqd_stride_v9;
+ #if defined(CONFIG_DEBUG_FS)
+               mqd->debugfs_show_mqd = debugfs_show_mqd;
diff --git a/queue-7.1/drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch b/queue-7.1/drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch
new file mode 100644 (file)
index 0000000..46c0890
--- /dev/null
@@ -0,0 +1,89 @@
+From 2b0386d4293920e690c0e017708f999b93cc729b Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <Yongqiang.Sun@amd.com>
+Date: Mon, 6 Jul 2026 15:15:07 -0400
+Subject: drm/amdkfd: fix 32-bit overflow in CWSR total size calculation
+
+From: Yongqiang Sun <Yongqiang.Sun@amd.com>
+
+commit 2b0386d4293920e690c0e017708f999b93cc729b upstream.
+
+total_cwsr_size was computed in 32-bit before being used as a BO/SVM
+allocation size.
+With large ctx_save_restore_area_size and debug_memory_size
+multiplied by the XCC count, the product can wrap,
+yielding an undersized CWSR save area that firmware later overruns.
+
+Promote total_cwsr_size to u64 and use check_add_overflow()/
+check_mul_overflow() in both kfd_queue_acquire_buffers() and
+kfd_queue_release_buffers().
+
+Signed-off-by: Yongqiang Sun <Yongqiang.Sun@amd.com>
+Reviewed-by: Philip Yang <philip.yang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 319f7e13423ae3f486b9aea82f9ad2d6af0ee608)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_queue.c |   23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+@@ -23,6 +23,7 @@
+  */
+ #include <linux/slab.h>
++#include <linux/overflow.h>
+ #include "kfd_priv.h"
+ #include "kfd_topology.h"
+ #include "kfd_svm.h"
+@@ -235,7 +236,7 @@ int kfd_queue_acquire_buffers(struct kfd
+       struct kfd_topology_device *topo_dev;
+       u64 expected_queue_size;
+       struct amdgpu_vm *vm;
+-      u32 total_cwsr_size;
++      u64 total_cwsr_size;
+       int err;
+       topo_dev = kfd_topology_device_by_id(pdd->dev->id);
+@@ -308,8 +309,14 @@ int kfd_queue_acquire_buffers(struct kfd
+               goto out_err_unreserve;
+       }
+-      total_cwsr_size = (properties->ctx_save_restore_area_size +
+-                         topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask);
++      total_cwsr_size = (u64)properties->ctx_save_restore_area_size +
++                        topo_dev->node_props.debug_memory_size;
++      if (check_mul_overflow(total_cwsr_size,
++                             NUM_XCC(pdd->dev->xcc_mask),
++                             &total_cwsr_size)) {
++              err = -EINVAL;
++              goto out_err_unreserve;
++      }
+       total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
+       err = kfd_queue_buffer_get(vm, (void *)properties->ctx_save_restore_area_address,
+@@ -344,7 +351,7 @@ out_err_release:
+ int kfd_queue_release_buffers(struct kfd_process_device *pdd, struct queue_properties *properties)
+ {
+       struct kfd_topology_device *topo_dev;
+-      u32 total_cwsr_size;
++      u64 total_cwsr_size;
+       kfd_queue_buffer_put(&properties->wptr_bo);
+       kfd_queue_buffer_put(&properties->rptr_bo);
+@@ -355,8 +362,12 @@ int kfd_queue_release_buffers(struct kfd
+       topo_dev = kfd_topology_device_by_id(pdd->dev->id);
+       if (!topo_dev)
+               return -EINVAL;
+-      total_cwsr_size = (properties->ctx_save_restore_area_size +
+-                         topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask);
++      total_cwsr_size = (u64)properties->ctx_save_restore_area_size +
++                        topo_dev->node_props.debug_memory_size;
++      if (check_mul_overflow(total_cwsr_size,
++                             NUM_XCC(pdd->dev->xcc_mask),
++                             &total_cwsr_size))
++              return -EINVAL;
+       total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
+       kfd_queue_buffer_svm_put(pdd, properties->ctx_save_restore_area_address, total_cwsr_size);
diff --git a/queue-7.1/drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch b/queue-7.1/drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch
new file mode 100644 (file)
index 0000000..658486d
--- /dev/null
@@ -0,0 +1,56 @@
+From b240f792ae02e9b687eafff934a39e57d1e45365 Mon Sep 17 00:00:00 2001
+From: Guangshuo Li <lgs201920130244@gmail.com>
+Date: Wed, 8 Jul 2026 18:51:15 +0800
+Subject: drm/amdkfd: free MQD managers on DQM init failures
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+commit b240f792ae02e9b687eafff934a39e57d1e45365 upstream.
+
+The change referenced by the Fixes tag releases the HIQ SDMA MQD trunk
+buffer when device_queue_manager_init() fails after it has been
+allocated.
+
+However, the same failure path can also be reached after
+init_mqd_managers() has succeeded. At that point dqm->mqd_mgrs[] contains
+per-type MQD manager objects owned by the device queue manager. The
+normal teardown path frees those objects from uninitialize(), but the
+initialization error path only frees dqm itself.
+
+Free the MQD managers from the initialization error path as well. This is
+safe for earlier failures because dqm is zeroed when allocated and
+init_mqd_managers() clears the entries it rolls back internally.
+
+Fixes: b7cccc8286bb ("drm/amdkfd: fix a memory leak in device_queue_manager_init()")
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Reviewed-by: Mukul Joshi <mukul.joshi@amd.com>
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 1fff2e07b6670bc5b8f7344a8708c136259cb176)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -2936,6 +2936,7 @@ static void deallocate_hiq_sdma_mqd(stru
+ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
+ {
+       struct device_queue_manager *dqm;
++      int i;
+       pr_debug("Loading device queue manager\n");
+@@ -3062,6 +3063,9 @@ struct device_queue_manager *device_queu
+               deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd);
+ out_free:
++      for (i = 0; i < KFD_MQD_TYPE_MAX; i++)
++              kfree(dqm->mqd_mgrs[i]);
++
+       kfree(dqm);
+       return NULL;
+ }
diff --git a/queue-7.1/drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch b/queue-7.1/drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch
new file mode 100644 (file)
index 0000000..b70544b
--- /dev/null
@@ -0,0 +1,90 @@
+From 8cd2ea7bab77b7aa087b1a6cc26d2df03c2a6ed9 Mon Sep 17 00:00:00 2001
+From: Xiaogang Chen <xiaogang.chen@amd.com>
+Date: Tue, 16 Jun 2026 17:18:59 -0500
+Subject: drm/amdkfd: Guard m->cp_hqd_eop_control setting by q->eop_ring_buffer_size
+
+From: Xiaogang Chen <xiaogang.chen@amd.com>
+
+commit 8cd2ea7bab77b7aa087b1a6cc26d2df03c2a6ed9 upstream.
+
+To avoid wraparound if the value is 0.
+
+Signed-off-by: Xiaogang Chen <xiaogang.chen@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit c0cae35661868af207077a4306bc42c7c972947c)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c   |    4 ++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c   |    4 ++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c   |    4 ++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c |    4 ++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c    |    4 ++--
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+@@ -198,8 +198,8 @@ static void update_mqd(struct mqd_manage
+        * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+        * is safe, giving a maximum field value of 0xA.
+        */
+-      m->cp_hqd_eop_control = min(0xA,
+-              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
++      m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
++              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
+       m->cp_hqd_eop_base_addr_lo =
+                       lower_32_bits(q->eop_ring_buffer_address >> 8);
+       m->cp_hqd_eop_base_addr_hi =
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -237,8 +237,8 @@ static void update_mqd(struct mqd_manage
+        * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+        * is safe, giving a maximum field value of 0xA.
+        */
+-      m->cp_hqd_eop_control = min(0xA,
+-              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
++      m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
++              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
+       m->cp_hqd_eop_base_addr_lo =
+                       lower_32_bits(q->eop_ring_buffer_address >> 8);
+       m->cp_hqd_eop_base_addr_hi =
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
+@@ -212,8 +212,8 @@ static void update_mqd(struct mqd_manage
+        * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+        * is safe, giving a maximum field value of 0xA.
+        */
+-      m->cp_hqd_eop_control = min(0xA,
+-              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
++      m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
++              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
+       m->cp_hqd_eop_base_addr_lo =
+                       lower_32_bits(q->eop_ring_buffer_address >> 8);
+       m->cp_hqd_eop_base_addr_hi =
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
+@@ -294,8 +294,8 @@ static void update_mqd(struct mqd_manage
+        * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+        * is safe, giving a maximum field value of 0xA.
+        */
+-      m->cp_hqd_eop_control = min(0xA,
+-              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
++      m->cp_hqd_eop_control = q->eop_ring_buffer_size ? min(0xA,
++              ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1) : 0;
+       m->cp_hqd_eop_base_addr_lo =
+                       lower_32_bits(q->eop_ring_buffer_address >> 8);
+       m->cp_hqd_eop_base_addr_hi =
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+@@ -209,8 +209,8 @@ static void __update_mqd(struct mqd_mana
+        * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+        * is safe, giving a maximum field value of 0xA.
+        */
+-      m->cp_hqd_eop_control |= min(0xA,
+-              order_base_2(q->eop_ring_buffer_size / 4) - 1);
++      m->cp_hqd_eop_control |= q->eop_ring_buffer_size ? min(0xA,
++              order_base_2(q->eop_ring_buffer_size / 4) - 1) : 0;
+       m->cp_hqd_eop_base_addr_lo =
+                       lower_32_bits(q->eop_ring_buffer_address >> 8);
+       m->cp_hqd_eop_base_addr_hi =
diff --git a/queue-7.1/drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch b/queue-7.1/drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch
new file mode 100644 (file)
index 0000000..ede0fcd
--- /dev/null
@@ -0,0 +1,74 @@
+From 9c8b85f95c1d4736b967e17b8eb4a463c055bea3 Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Thu, 25 Jun 2026 10:09:13 -0400
+Subject: drm/amdkfd: Use kvcalloc to allocate arrays
+
+From: David Francis <David.Francis@amd.com>
+
+commit 9c8b85f95c1d4736b967e17b8eb4a463c055bea3 upstream.
+
+There were a few instances in kfd_chardev.c of kvzalloc being
+used to allocate memory for an array.
+
+Switch those to kvcalloc, which
+- is the standard way of allocating a zero-initialized array
+- does a check for the mul overflowing
+
+Signed-off-by: David Francis <David.Francis@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 60b048c93f7a3add39757ad65fe2bb6e58eeae23)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1837,13 +1837,13 @@ static int criu_checkpoint_devices(struc
+       struct kfd_criu_device_bucket *device_buckets = NULL;
+       int ret = 0, i;
+-      device_buckets = kvzalloc(num_devices * sizeof(*device_buckets), GFP_KERNEL);
++      device_buckets = kvcalloc(num_devices, sizeof(*device_buckets), GFP_KERNEL);
+       if (!device_buckets) {
+               ret = -ENOMEM;
+               goto exit;
+       }
+-      device_priv = kvzalloc(num_devices * sizeof(*device_priv), GFP_KERNEL);
++      device_priv = kvcalloc(num_devices, sizeof(*device_priv), GFP_KERNEL);
+       if (!device_priv) {
+               ret = -ENOMEM;
+               goto exit;
+@@ -1963,17 +1963,17 @@ static int criu_checkpoint_bos(struct kf
+       int ret = 0, pdd_index, bo_index = 0, id;
+       void *mem;
+-      bo_buckets = kvzalloc(num_bos * sizeof(*bo_buckets), GFP_KERNEL);
++      bo_buckets = kvcalloc(num_bos, sizeof(*bo_buckets), GFP_KERNEL);
+       if (!bo_buckets)
+               return -ENOMEM;
+-      bo_privs = kvzalloc(num_bos * sizeof(*bo_privs), GFP_KERNEL);
++      bo_privs = kvcalloc(num_bos, sizeof(*bo_privs), GFP_KERNEL);
+       if (!bo_privs) {
+               ret = -ENOMEM;
+               goto exit;
+       }
+-      files = kvzalloc(num_bos * sizeof(struct file *), GFP_KERNEL);
++      files = kvcalloc(num_bos, sizeof(struct file *), GFP_KERNEL);
+       if (!files) {
+               ret = -ENOMEM;
+               goto exit;
+@@ -2510,7 +2510,7 @@ static int criu_restore_bos(struct kfd_p
+       if (!bo_buckets)
+               return -ENOMEM;
+-      files = kvzalloc(args->num_bos * sizeof(struct file *), GFP_KERNEL);
++      files = kvcalloc(args->num_bos, sizeof(struct file *), GFP_KERNEL);
+       if (!files) {
+               ret = -ENOMEM;
+               goto exit;
diff --git a/queue-7.1/drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch b/queue-7.1/drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch
new file mode 100644 (file)
index 0000000..8699859
--- /dev/null
@@ -0,0 +1,67 @@
+From 17e2030f37600994440f875dc410615d5c66ee6d Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <zhengxingda@iscas.ac.cn>
+Date: Tue, 14 Jul 2026 15:36:41 +0800
+Subject: drm/imagination: acquire vm_ctx->lock before mapping memory to GPU VM
+
+From: Icenowy Zheng <zhengxingda@iscas.ac.cn>
+
+commit 17e2030f37600994440f875dc410615d5c66ee6d upstream.
+
+The drm gpuvm code doesn't protect find operation against map operation,
+and the driver needs to ensure a map operation shouldn't happen when a
+find operation is in progress.
+
+In some cases a find operation will be in progress when doing map/unmap
+operations, and the find operation will do a NULL pointer dereference.
+
+An example of the stack trace of such NULL dereference is shown below:
+
+```
+Unable to handle kernel access to user memory without uaccess routines at
+virtual address 0000000000000010
+
+[<ffffffff01e989d4>] drm_gpuva_find+0x28/0x6c [drm_gpuvm]
+[<ffffffff01ed3a40>] pvr_vm_unmap+0x34/0x68 [powervr]
+[<ffffffff01ec69da>] pvr_ioctl_vm_unmap+0x2e/0x50 [powervr]
+[<ffffffff8080ce0a>] drm_ioctl_kernel+0x8e/0xdc
+[<ffffffff8080d016>] drm_ioctl+0x1be/0x3e0
+[<ffffffff802bec3e>] __riscv_sys_ioctl+0xba/0xc4
+[<ffffffff80d858b2>] do_trap_ecall_u+0x23e/0x3f4
+[<ffffffff80d92288>] handle_exception+0x168/0x174
+```
+
+As all occurences of drm_gpuva_find*() are already guarded by
+vm_ctx->lock, make pvr_vm_map() to acquire this lock to prevent
+disturbing any find operation. This fixes the NULL deference problem in
+drm_gpuva_find*().
+
+Cc: stable@vger.kernel.org
+Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
+Fixes: 4bc736f890ce ("drm/imagination: vm: make use of GPUVM's drm_exec helper")
+Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
+Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
+Link: https://patch.msgid.link/20260714073641.1935075-1-zhengxingda@iscas.ac.cn
+Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/imagination/pvr_vm.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/imagination/pvr_vm.c
++++ b/drivers/gpu/drm/imagination/pvr_vm.c
+@@ -747,6 +747,7 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx
+       pvr_gem_object_get(pvr_obj);
++      mutex_lock(&vm_ctx->lock);
+       err = drm_gpuvm_exec_lock(&vm_exec);
+       if (err)
+               goto err_cleanup;
+@@ -756,6 +757,7 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx
+       drm_gpuvm_exec_unlock(&vm_exec);
+ err_cleanup:
++      mutex_unlock(&vm_ctx->lock);
+       pvr_vm_bind_op_fini(&bind_op);
+       return err;
diff --git a/queue-7.1/drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch b/queue-7.1/drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch
new file mode 100644 (file)
index 0000000..d05253d
--- /dev/null
@@ -0,0 +1,180 @@
+From 4af24c27a39ba147a613a09e10b9e0f7294524c0 Mon Sep 17 00:00:00 2001
+From: Brajesh Gupta <brajesh.gupta@imgtec.com>
+Date: Tue, 30 Jun 2026 21:10:07 +0530
+Subject: drm/imagination: Fix double call to drm_sched_entity_fini()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Brajesh Gupta <brajesh.gupta@imgtec.com>
+
+commit 4af24c27a39ba147a613a09e10b9e0f7294524c0 upstream.
+
+Call sequence of double call:
+pvr_context_destroy
+  pvr_context_kill_queues
+    pvr_queue_kill
+      drm_sched_entity_destroy
+        drm_sched_entity_fini // here
+  pvr_context_put
+    kref_put(..., pvr_context_release)
+      pvr_context_destroy_queues
+        pvr_queue_destroy
+          drm_sched_entity_fini // here
+
+Call to drm_sched_entity_destroy() from pvr_context_kill_queues() calls
+drm_sched_entity_flush() + drm_sched_entity_fini().
+drm_sched_entity_flush() ensures all pending jobs are completed and
+drm_sched_entity_fini() ensures no further submission is allowed as
+per expectation from pvr_context_kill_queues(). Double call to
+drm_sched_entity_fini() is misuse of the API so keep call only in
+pvr_context_create() failure path.
+
+Stack trace for issue with addition of refcounting for DRM entity
+stats in commit fd177135f0e6 ("drm/sched: Account entity GPU time"):
+
+[  789.490527] ------------[ cut here ]------------
+[  789.490559] refcount_t: underflow; use-after-free.
+[  789.490657] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0xf4/0x144, CPU#0: kworker/u16:1/440
+[  789.490695] Modules linked in: powervr drm_gpuvm drm_exec gpu_sched drm_shmem_helper xhci_plat_hcd xhci_hcd dwc3 usbcore usb_common snd_soc_simple_card snd_soc_simple_card_utils sa2ul sha512 sha256 dwc3_am62 sha1 authenc rti_wdt libsha512 at24 sch_fq_codel fuse dm_mod ipv6
+[  789.490798] CPU: 0 UID: 0 PID: 440 Comm: kworker/u16:1 Not tainted 7.0.0-rc7-02049-g5e2c0700091b #22 PREEMPT
+[  789.490809] Hardware name: Texas Instruments AM625 SK (DT)
+[  789.490815] Workqueue: powervr-sched pvr_queue_fence_release_work [powervr]
+[  789.490868] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[  789.490876] pc : refcount_warn_saturate+0xf4/0x144
+[  789.490884] lr : refcount_warn_saturate+0xf4/0x144
+[  789.490892] sp : ffff8000822cbcc0
+[  789.490895] x29: ffff8000822cbcc0 x28: 0000000000000000 x27: 0000000000000000
+[  789.490909] x26: 0000000000000000 x25: ffff800081b1e338 x24: ffff000004541405
+[  789.490922] x23: ffff000004bea950 x22: ffff00000042e400 x21: ffff000007123e30
+[  789.490935] x20: ffff000007123000 x19: ffff000007a80d50 x18: fffffffffffe7768
+[  789.490948] x17: 74736574202c6e6f x16: 697461746e656d65 x15: ffff800081b269f0
+[  789.490962] x14: 0000000000000030 x13: ffff800081b26a70 x12: 0000000000000211
+[  789.490975] x11: 00000000000000c0 x10: 0000000000000b50 x9 : ffff8000822cbb30
+[  789.490988] x8 : ffff0000014e7bb0 x7 : ffff00007725e780 x6 : 0000000372a05f49
+[  789.491001] x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000010
+[  789.491013] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000014e7000
+[  789.491027] Call trace:
+[  789.491032]  refcount_warn_saturate+0xf4/0x144 (P)
+[  789.491043]  drm_sched_entity_fini+0x164/0x18c [gpu_sched]
+[  789.491081]  pvr_queue_destroy+0x64/0x134 [powervr]
+[  789.491110]  pvr_context_destroy_queues+0x34/0x64 [powervr]
+[  789.491138]  pvr_context_release+0x70/0xac [powervr]
+[  789.491166]  pvr_context_put.part.0+0x5c/0x7c [powervr]
+[  789.491193]  pvr_context_put+0x14/0x24 [powervr]
+[  789.491221]  pvr_queue_fence_release_work+0x20/0x38 [powervr]
+[  789.491249]  process_one_work+0x160/0x4c4
+[  789.491264]  worker_thread+0x188/0x310
+[  789.491276]  kthread+0x130/0x13c
+[  789.491287]  ret_from_fork+0x10/0x20
+[  789.491300] ---[ end trace 0000000000000000 ]---
+
+Fixes: eaf01ee5ba28 ("drm/imagination: Implement job submission and scheduling")
+Cc: stable@vger.kernel.org
+Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
+Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
+Link: https://patch.msgid.link/20260630-b4-sched_fix-v7-1-71aa39c62627@imgtec.com
+Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/imagination/pvr_context.c |   18 ++++++++++--------
+ drivers/gpu/drm/imagination/pvr_queue.c   |    6 ++++--
+ drivers/gpu/drm/imagination/pvr_queue.h   |    2 +-
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/imagination/pvr_context.c
++++ b/drivers/gpu/drm/imagination/pvr_context.c
+@@ -161,22 +161,24 @@ ctx_fw_data_init(void *cpu_ptr, void *pr
+ /**
+  * pvr_context_destroy_queues() - Destroy all queues attached to a context.
+  * @ctx: Context to destroy queues on.
++ * @cleanup_queue_entity: Whether to cleanup the queue entity e.g. context
++ * creation failure path.
+  *
+  * Should be called when the last reference to a context object is dropped.
+  * It releases all resources attached to the queues bound to this context.
+  */
+-static void pvr_context_destroy_queues(struct pvr_context *ctx)
++static void pvr_context_destroy_queues(struct pvr_context *ctx, bool cleanup_queue_entity)
+ {
+       switch (ctx->type) {
+       case DRM_PVR_CTX_TYPE_RENDER:
+-              pvr_queue_destroy(ctx->queues.fragment);
+-              pvr_queue_destroy(ctx->queues.geometry);
++              pvr_queue_destroy(ctx->queues.fragment, cleanup_queue_entity);
++              pvr_queue_destroy(ctx->queues.geometry, cleanup_queue_entity);
+               break;
+       case DRM_PVR_CTX_TYPE_COMPUTE:
+-              pvr_queue_destroy(ctx->queues.compute);
++              pvr_queue_destroy(ctx->queues.compute, cleanup_queue_entity);
+               break;
+       case DRM_PVR_CTX_TYPE_TRANSFER_FRAG:
+-              pvr_queue_destroy(ctx->queues.transfer);
++              pvr_queue_destroy(ctx->queues.transfer, cleanup_queue_entity);
+               break;
+       }
+ }
+@@ -240,7 +242,7 @@ static int pvr_context_create_queues(str
+       return -EINVAL;
+ err_destroy_queues:
+-      pvr_context_destroy_queues(ctx);
++      pvr_context_destroy_queues(ctx, true);
+       return err;
+ }
+@@ -356,7 +358,7 @@ err_destroy_fw_obj:
+       pvr_fw_object_destroy(ctx->fw_obj);
+ err_destroy_queues:
+-      pvr_context_destroy_queues(ctx);
++      pvr_context_destroy_queues(ctx, true);
+ err_free_ctx_data:
+       kfree(ctx->data);
+@@ -382,7 +384,7 @@ pvr_context_release(struct kref *ref_cou
+       spin_unlock(&pvr_dev->ctx_list_lock);
+       xa_erase(&pvr_dev->ctx_ids, ctx->ctx_id);
+-      pvr_context_destroy_queues(ctx);
++      pvr_context_destroy_queues(ctx, false);
+       pvr_fw_object_destroy(ctx->fw_obj);
+       kfree(ctx->data);
+       pvr_vm_context_put(ctx->vm_ctx);
+--- a/drivers/gpu/drm/imagination/pvr_queue.c
++++ b/drivers/gpu/drm/imagination/pvr_queue.c
+@@ -1401,11 +1401,12 @@ void pvr_queue_kill(struct pvr_queue *qu
+ /**
+  * pvr_queue_destroy() - Destroy a queue.
+  * @queue: The queue to destroy.
++ * @cleanup_queue_entity: Whether to cleanup the queue entity.
+  *
+  * Cleanup the queue and free the resources attached to it. Should be
+  * called from the context release function.
+  */
+-void pvr_queue_destroy(struct pvr_queue *queue)
++void pvr_queue_destroy(struct pvr_queue *queue, bool cleanup_queue_entity)
+ {
+       if (!queue)
+               return;
+@@ -1415,7 +1416,8 @@ void pvr_queue_destroy(struct pvr_queue
+       mutex_unlock(&queue->ctx->pvr_dev->queues.lock);
+       drm_sched_fini(&queue->scheduler);
+-      drm_sched_entity_fini(&queue->entity);
++      if (cleanup_queue_entity)
++              drm_sched_entity_fini(&queue->entity);
+       if (WARN_ON(queue->last_queued_job_scheduled_fence))
+               dma_fence_put(queue->last_queued_job_scheduled_fence);
+--- a/drivers/gpu/drm/imagination/pvr_queue.h
++++ b/drivers/gpu/drm/imagination/pvr_queue.h
+@@ -158,7 +158,7 @@ struct pvr_queue *pvr_queue_create(struc
+ void pvr_queue_kill(struct pvr_queue *queue);
+-void pvr_queue_destroy(struct pvr_queue *queue);
++void pvr_queue_destroy(struct pvr_queue *queue, bool cleanup_queue_entity);
+ void pvr_queue_process(struct pvr_queue *queue);
diff --git a/queue-7.1/drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch b/queue-7.1/drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch
new file mode 100644 (file)
index 0000000..d7c4a21
--- /dev/null
@@ -0,0 +1,87 @@
+From cf385cf6e713eba0720651174dac0b2d2f5bb8f8 Mon Sep 17 00:00:00 2001
+From: Luigi Santivetti <luigi.santivetti@imgtec.com>
+Date: Tue, 7 Jul 2026 16:17:16 +0100
+Subject: drm/imagination: fix error checking of pvr_vm_context_lookup()
+
+From: Luigi Santivetti <luigi.santivetti@imgtec.com>
+
+commit cf385cf6e713eba0720651174dac0b2d2f5bb8f8 upstream.
+
+Since pvr_vm_context_lookup() returns either NULL or a pointer, then stop
+using IS_ERR() for checking the return value.
+
+Using IS_ERR() leads to the kernel oops reported below. It can be
+reproduced by passing an invalid VM context handle from userspace to the
+DRM_IOCTL_PVR_CREATE_CONTEXT ioctl.
+
+[   92.733119] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000148
+[   92.742042] Mem abort info:
+[   92.744890]   ESR = 0x0000000096000004
+[   92.748686]   EC = 0x25: DABT (current EL), IL = 32 bits
+[   92.754020]   SET = 0, FnV = 0
+[   92.757154]   EA = 0, S1PTW = 0
+[   92.760337]   FSC = 0x04: level 0 translation fault
+[   92.765243] Data abort info:
+[   92.768129]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[   92.773626]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[   92.778763]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[   92.784098] user pgtable: 4k pages, 48-bit VAs, pgdp=000000088ed23000
+[   92.790550] [0000000000000148] pgd=0000000000000000, p4d=0000000000000000
+[   92.797381] Internal error: Oops: 0000000096000004 [#1]  SMP
+[   92.803027] Modules linked in: powervr
+[   92.852533] CPU: 0 UID: 0 PID: 409 Comm: triangle Not tainted 7.1.0-rc5-g98b46e693b91 #1 PREEMPT
+[   92.861385] Hardware name: Texas Instruments AM68 SK (DT)
+[   92.866766] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[   92.873709] pc : pvr_vm_get_fw_mem_context+0x0/0xc [powervr]
+[   92.879376] lr : pvr_queue_create+0x26c/0x440 [powervr]
+[   92.884595] sp : ffff8000837fbb00
+[   92.887895] x29: ffff8000837fbb60 x28: 0000000000000000 x27: ffff8000837fbce8
+[   92.895015] x26: ffff000807f61a40 x25: ffff000807f61a00 x24: ffff000807f64400
+[   92.902135] x23: ffff00080a5ab000 x22: ffff800079b24730 x21: ffff000807f61800
+[   92.909254] x20: ffff00080999e680 x19: 0000000000000000 x18: 0000000000000000
+[   92.916373] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000001
+[   92.923492] x14: 0000000000000000 x13: 0000000000000002 x12: ffff80008145b298
+[   92.930611] x11: ffff8000844e5000 x10: ffff80008165a130 x9 : 0000000000000100
+[   92.937730] x8 : 0000000000000001 x7 : ffff0008076b27e0 x6 : ffff00080ec43b7c
+[   92.944850] x5 : ffff00080ec43b78 x4 : 0000000000000000 x3 : ffff00080999e680
+[   92.951968] x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
+[   92.959088] Call trace:
+[   92.961521]  pvr_vm_get_fw_mem_context+0x0/0xc [powervr] (P)
+[   92.967173]  pvr_context_create+0x190/0x410 [powervr]
+[   92.972218]  pvr_ioctl_create_context+0x44/0x8c [powervr]
+[   92.977608]  drm_ioctl_kernel+0xbc/0x124 [drm]
+[   92.982127]  drm_ioctl+0x1f8/0x4dc [drm]
+[   92.986098]  __arm64_sys_ioctl+0xac/0x104
+[   92.990102]  invoke_syscall+0x54/0x10c
+[   92.993842]  el0_svc_common.constprop.0+0x40/0xe0
+[   92.998532]  do_el0_svc+0x1c/0x28
+[   93.001835]  el0_svc+0x38/0x11c
+[   93.004969]  el0t_64_sync_handler+0xa0/0xe4
+[   93.009139]  el0t_64_sync+0x198/0x19c
+[   93.012792] Code: aa1703e0 d2800014 95cb0ba4 17ffffe8 (f940a400)
+[   93.018869] ---[ end trace 0000000000000000 ]---
+
+Fixes: d2d79d29bb98 ("drm/imagination: Implement context creation/destruction ioctls")
+Cc: stable@vger.kernel.org
+Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
+Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
+Link: https://patch.msgid.link/20260707-staging-ddkopsrc-2435-v1-1-24e160d44476@imgtec.com
+Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/imagination/pvr_context.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/imagination/pvr_context.c
++++ b/drivers/gpu/drm/imagination/pvr_context.c
+@@ -309,8 +309,8 @@ int pvr_context_create(struct pvr_file *
+               goto err_free_ctx;
+       ctx->vm_ctx = pvr_vm_context_lookup(pvr_file, args->vm_context_handle);
+-      if (IS_ERR(ctx->vm_ctx)) {
+-              err = PTR_ERR(ctx->vm_ctx);
++      if (!ctx->vm_ctx) {
++              err = -EINVAL;
+               goto err_free_ctx;
+       }
diff --git a/queue-7.1/drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch b/queue-7.1/drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch
new file mode 100644 (file)
index 0000000..c422671
--- /dev/null
@@ -0,0 +1,59 @@
+From 8dc8f3f4c2382fb7d1b1986ba8f33a2466cd3d7a Mon Sep 17 00:00:00 2001
+From: Shuvam Pandey <shuvampandey1@gmail.com>
+Date: Wed, 1 Jul 2026 11:44:34 -0700
+Subject: drm/imagination: Fix user array stride in pvr_set_uobj_array()
+
+From: Shuvam Pandey <shuvampandey1@gmail.com>
+
+commit 8dc8f3f4c2382fb7d1b1986ba8f33a2466cd3d7a upstream.
+
+pvr_set_uobj_array() copies an array of kernel objects to a userspace
+array whose element size is described by out->stride. When out->stride
+is different from the kernel object size, the slow path advances the
+userspace pointer by the kernel object size and the kernel pointer by the
+userspace stride.
+
+This reverses the intended layout. For larger userspace strides, later
+copies read from the wrong kernel addresses. For smaller userspace
+strides, later copies are written at the wrong userspace offsets. The
+padding clear is also done only for the first element instead of the
+padding area for each element.
+
+Advance the userspace pointer by out->stride and the kernel pointer by
+obj_size, and clear per-element padding while the current userspace
+pointer is still available.
+
+Fixes: f99f5f3ea7ef ("drm/imagination: Add GPU ID parsing and firmware loading")
+Cc: stable@vger.kernel.org # v6.8+
+Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
+Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
+Link: https://patch.msgid.link/6a456012.eb165e5c.113c2a.b71d@mx.google.com
+Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/imagination/pvr_drv.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/imagination/pvr_drv.c
++++ b/drivers/gpu/drm/imagination/pvr_drv.c
+@@ -1254,14 +1254,13 @@ pvr_set_uobj_array(const struct drm_pvr_
+                       if (copy_to_user(out_ptr, in_ptr, cpy_elem_size))
+                               return -EFAULT;
+-                      out_ptr += obj_size;
+-                      in_ptr += out->stride;
+-              }
++                      if (out->stride > obj_size &&
++                          clear_user(out_ptr + cpy_elem_size, out->stride - obj_size)) {
++                              return -EFAULT;
++                      }
+-              if (out->stride > obj_size &&
+-                  clear_user(u64_to_user_ptr(out->array + obj_size),
+-                             out->stride - obj_size)) {
+-                      return -EFAULT;
++                      out_ptr += out->stride;
++                      in_ptr += obj_size;
+               }
+       }
index f575d7ac8ae76c5584d41394587ddda1845d8db6..352f33679598626f253a93007690b561918a485d 100644 (file)
@@ -96,17 +96,15 @@ Link: https://patch.msgid.link/20260710191027.260160-2-nitin.r.gote@intel.com
 Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 ---
- drivers/gpu/drm/xe/xe_bo.c       | 24 ++++++++++++++++++++----
- drivers/gpu/drm/xe/xe_bo.h       |  3 ++-
- drivers/gpu/drm/xe/xe_bo_types.h |  2 ++
- drivers/gpu/drm/xe/xe_dma_buf.c  |  2 +-
+ drivers/gpu/drm/xe/xe_bo.c       |   24 ++++++++++++++++++++----
+ drivers/gpu/drm/xe/xe_bo.h       |    3 ++-
+ drivers/gpu/drm/xe/xe_bo_types.h |    2 ++
+ drivers/gpu/drm/xe/xe_dma_buf.c  |    2 +-
  4 files changed, 25 insertions(+), 6 deletions(-)
 
-diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
-index 4c80bac67622..ddbaf4242c79 100644
 --- a/drivers/gpu/drm/xe/xe_bo.c
 +++ b/drivers/gpu/drm/xe/xe_bo.c
-@@ -1349,7 +1349,7 @@ int xe_bo_notifier_prepare_pinned(struct xe_bo *bo)
+@@ -1368,7 +1368,7 @@ int xe_bo_notifier_prepare_pinned(struct
                backup = xe_bo_init_locked(xe, NULL, NULL, bo->ttm.base.resv, NULL, xe_bo_size(bo),
                                           DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
                                           XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
@@ -115,7 +113,7 @@ index 4c80bac67622..ddbaf4242c79 100644
                if (IS_ERR(backup)) {
                        drm_exec_retry_on_contention(&exec);
                        ret = PTR_ERR(backup);
-@@ -1490,7 +1490,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
+@@ -1509,7 +1509,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
                                                   xe_bo_size(bo),
                                                   DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
                                                   XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
@@ -124,7 +122,7 @@ index 4c80bac67622..ddbaf4242c79 100644
                        if (IS_ERR(backup)) {
                                drm_exec_retry_on_contention(&exec);
                                ret = PTR_ERR(backup);
-@@ -1826,6 +1826,8 @@ static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo)
+@@ -1845,6 +1845,8 @@ static void xe_ttm_bo_destroy(struct ttm
  
        if (bo->ttm.base.import_attach)
                drm_prime_gem_destroy(&bo->ttm.base, NULL);
@@ -133,7 +131,7 @@ index 4c80bac67622..ddbaf4242c79 100644
        drm_gem_object_release(&bo->ttm.base);
  
        xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list));
-@@ -2283,6 +2285,8 @@ void xe_bo_free(struct xe_bo *bo)
+@@ -2302,6 +2304,8 @@ void xe_bo_free(struct xe_bo *bo)
   * @cpu_caching: The cpu caching used for system memory backing store.
   * @type: The TTM buffer object type.
   * @flags: XE_BO_FLAG_ flags.
@@ -142,7 +140,7 @@ index 4c80bac67622..ddbaf4242c79 100644
   * @exec: The drm_exec transaction to use for exhaustive eviction.
   *
   * Initialize or create an xe buffer object. On failure, any allocated buffer
-@@ -2294,7 +2298,8 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
+@@ -2313,7 +2317,8 @@ struct xe_bo *xe_bo_init_locked(struct x
                                struct xe_tile *tile, struct dma_resv *resv,
                                struct ttm_lru_bulk_move *bulk, size_t size,
                                u16 cpu_caching, enum ttm_bo_type type,
@@ -152,7 +150,7 @@ index 4c80bac67622..ddbaf4242c79 100644
  {
        struct ttm_operation_ctx ctx = {
                .interruptible = true,
-@@ -2383,6 +2388,17 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
+@@ -2402,6 +2407,17 @@ struct xe_bo *xe_bo_init_locked(struct x
        placement = (type == ttm_bo_type_sg ||
                     bo->flags & XE_BO_FLAG_DEFER_BACKING) ? &sys_placement :
                &bo->placement;
@@ -170,7 +168,7 @@ index 4c80bac67622..ddbaf4242c79 100644
        err = ttm_bo_init_reserved(&xe->ttm, &bo->ttm, type,
                                   placement, alignment,
                                   &ctx, NULL, resv, xe_ttm_bo_destroy);
-@@ -2500,7 +2516,7 @@ __xe_bo_create_locked(struct xe_device *xe,
+@@ -2519,7 +2535,7 @@ __xe_bo_create_locked(struct xe_device *
                               vm && !xe_vm_in_fault_mode(vm) &&
                               flags & XE_BO_FLAG_USER ?
                               &vm->lru_bulk_move : NULL, size,
@@ -179,11 +177,9 @@ index 4c80bac67622..ddbaf4242c79 100644
        if (IS_ERR(bo))
                return bo;
  
-diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
-index 6340317f7d2e..7ae1d9ac0574 100644
 --- a/drivers/gpu/drm/xe/xe_bo.h
 +++ b/drivers/gpu/drm/xe/xe_bo.h
-@@ -118,7 +118,8 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
+@@ -118,7 +118,8 @@ struct xe_bo *xe_bo_init_locked(struct x
                                struct xe_tile *tile, struct dma_resv *resv,
                                struct ttm_lru_bulk_move *bulk, size_t size,
                                u16 cpu_caching, enum ttm_bo_type type,
@@ -193,8 +189,6 @@ index 6340317f7d2e..7ae1d9ac0574 100644
  struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
                                  struct xe_vm *vm, size_t size,
                                  enum ttm_bo_type type, u32 flags,
-diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
-index fcc63ae3f455..e45f24301050 100644
 --- a/drivers/gpu/drm/xe/xe_bo_types.h
 +++ b/drivers/gpu/drm/xe/xe_bo_types.h
 @@ -36,6 +36,8 @@ struct xe_bo {
@@ -206,11 +200,9 @@ index fcc63ae3f455..e45f24301050 100644
        /** @flags: flags for this buffer object */
        u32 flags;
        /** @vm: VM this BO is attached to, for extobj this will be NULL */
-diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
-index 8a920e58245c..bf0728838ead 100644
 --- a/drivers/gpu/drm/xe/xe_dma_buf.c
 +++ b/drivers/gpu/drm/xe/xe_dma_buf.c
-@@ -302,7 +302,7 @@ xe_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
+@@ -302,7 +302,7 @@ xe_dma_buf_create_obj(struct drm_device
  
                bo = xe_bo_init_locked(xe, NULL, NULL, resv, NULL, dma_buf->size,
                                       0, /* Will require 1way or 2way for vm_bind */
@@ -219,6 +211,3 @@ index 8a920e58245c..bf0728838ead 100644
                drm_exec_retry_on_contention(&exec);
                if (IS_ERR(bo)) {
                        ret = PTR_ERR(bo);
--- 
-2.55.0
-
diff --git a/queue-7.1/drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch b/queue-7.1/drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch
new file mode 100644 (file)
index 0000000..577d90e
--- /dev/null
@@ -0,0 +1,80 @@
+From 57441577bac3637473da2c9644336eaa0ac5732f Mon Sep 17 00:00:00 2001
+From: Arvind Yadav <arvind.yadav@intel.com>
+Date: Tue, 26 May 2026 19:24:47 +0530
+Subject: drm/xe/madvise: Skip invalidation for purgeable state updates
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arvind Yadav <arvind.yadav@intel.com>
+
+commit 57441577bac3637473da2c9644336eaa0ac5732f upstream.
+
+Purgeable state updates only change VMA/BO metadata. They do not zap
+PTEs when switching between DONTNEED and WILLNEED. PTEs are zapped
+later if the BO is actually purged.
+
+xe_vm_invalidate_madvise_range() waits on the VM dma-resv before checking
+vma->skip_invalidation. Since purgeable madvise marks all affected VMAs to
+skip invalidation, this wait is unnecessary and can stall on unrelated
+in-flight work.
+
+Skip the invalidate path entirely for purgeable state updates.
+
+v2:
+  - Replace inline 'args->type != DRM_XE_VMA_ATTR_PURGEABLE_STATE'
+    check with a small helper madvise_range_needs_invalidation().
+    (Himal)
+
+Suggested-by: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
+Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Link: https://patch.msgid.link/20260526135447.2973029-1-arvind.yadav@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe")
+Cc: <stable@vger.kernel.org> # v6.18+
+(cherry picked from commit 134377098b9c14abd31c3bcac00c9653f0f0c4c3)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_vm_madvise.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
++++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
+@@ -332,6 +332,20 @@ static int xe_vm_invalidate_madvise_rang
+       return err;
+ }
++/**
++ * madvise_range_needs_invalidation() - Check whether madvise needs invalidation
++ * @args: madvise ioctl arguments
++ *
++ * Purgeable state updates only touch VMA/BO metadata. PTEs stay valid and are
++ * zapped only if the BO is later purged.
++ *
++ * Return: true when the update needs PTE invalidation.
++ */
++static bool madvise_range_needs_invalidation(const struct drm_xe_madvise *args)
++{
++      return args->type != DRM_XE_VMA_ATTR_PURGEABLE_STATE;
++}
++
+ static bool madvise_args_are_sane(struct xe_device *xe, const struct drm_xe_madvise *args)
+ {
+       if (XE_IOCTL_DBG(xe, !args))
+@@ -708,8 +722,9 @@ int xe_vm_madvise_ioctl(struct drm_devic
+       madvise_funcs[attr_type](xe, vm, madvise_range.vmas, madvise_range.num_vmas, args,
+                                &details);
+-      err = xe_vm_invalidate_madvise_range(vm, madvise_range.addr,
+-                                           madvise_range.addr + args->range);
++      if (madvise_range_needs_invalidation(args))
++              err = xe_vm_invalidate_madvise_range(vm, madvise_range.addr,
++                                                   madvise_range.addr + args->range);
+       if (madvise_range.has_svm_userptr_vmas)
+               xe_svm_notifier_unlock(vm);
diff --git a/queue-7.1/drm-xe-nvm-fix-writable-override-for-cri.patch b/queue-7.1/drm-xe-nvm-fix-writable-override-for-cri.patch
new file mode 100644 (file)
index 0000000..2e237b0
--- /dev/null
@@ -0,0 +1,79 @@
+From c473761f8178760b915633332908409c73bfdb9e Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Tue, 14 Jul 2026 08:54:17 +0300
+Subject: drm/xe/nvm: fix writable override for CRI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+commit c473761f8178760b915633332908409c73bfdb9e upstream.
+
+The witable override should be set when FDO_MODE bit is enabled.
+Fix the comparison to distingush this case from legacy systems
+where bit should be disabled to have override.
+
+Cc: stable@vger.kernel.org
+Fixes: 9dde74fd9e65 ("drm/xe/nvm: enable cri platform")
+Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://patch.msgid.link/20260714-cri_nvm_fdo_flip-v2-1-14580e71b58e@intel.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+(cherry picked from commit 2007be18d2318a59748da5da1b8968042213d5f1)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_nvm.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_nvm.c b/drivers/gpu/drm/xe/xe_nvm.c
+index 33487e91f366..1ea67eaeae24 100644
+--- a/drivers/gpu/drm/xe/xe_nvm.c
++++ b/drivers/gpu/drm/xe/xe_nvm.c
+@@ -60,35 +60,40 @@ static bool xe_nvm_writable_override(struct xe_device *xe)
+       struct xe_mmio *mmio = xe_root_tile_mmio(xe);
+       bool writable_override;
+       struct xe_reg reg;
+-      u32 test_bit;
++      u32 test_bit, test_val;
+       switch (xe->info.platform) {
+       case XE_CRESCENTISLAND:
+               reg = PCODE_SCRATCH(0);
+               test_bit = FDO_MODE;
++              test_val = FDO_MODE;
+               break;
+       case XE_BATTLEMAGE:
+               reg = HECI_FWSTS2(DG2_GSC_HECI2_BASE);
+               test_bit = HECI_FW_STATUS_2_NVM_ACCESS_MODE;
++              test_val = 0;
+               break;
+       case XE_PVC:
+               reg = HECI_FWSTS2(PVC_GSC_HECI2_BASE);
+               test_bit = HECI_FW_STATUS_2_NVM_ACCESS_MODE;
++              test_val = 0;
+               break;
+       case XE_DG2:
+               reg = HECI_FWSTS2(DG2_GSC_HECI2_BASE);
+               test_bit = HECI_FW_STATUS_2_NVM_ACCESS_MODE;
++              test_val = 0;
+               break;
+       case XE_DG1:
+               reg = HECI_FWSTS2(DG1_GSC_HECI2_BASE);
+               test_bit = HECI_FW_STATUS_2_NVM_ACCESS_MODE;
++              test_val = 0;
+               break;
+       default:
+               drm_err(&xe->drm, "Unknown platform\n");
+               return true;
+       }
+-      writable_override = !(xe_mmio_read32(mmio, reg) & test_bit);
++      writable_override = (xe_mmio_read32(mmio, reg) & test_bit) == test_val;
+       if (writable_override)
+               drm_info(&xe->drm, "NVM access overridden by jumper\n");
+       return writable_override;
+-- 
+2.55.0
+
diff --git a/queue-7.1/drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch b/queue-7.1/drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch
new file mode 100644 (file)
index 0000000..7218a32
--- /dev/null
@@ -0,0 +1,65 @@
+From 6384271ac1ac0099198d15df79212a19ebdb929d Mon Sep 17 00:00:00 2001
+From: Zongyao Bai <zongyao.bai@intel.com>
+Date: Tue, 14 Jul 2026 23:24:32 +0000
+Subject: drm/xe/pt: Reset current_op in xe_pt_update_ops_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zongyao Bai <zongyao.bai@intel.com>
+
+commit 6384271ac1ac0099198d15df79212a19ebdb929d upstream.
+
+xe_pt_update_ops_init() fails to reset current_op to 0. On the
+vm_bind path, ops_execute() calls xe_pt_update_ops_prepare() inside
+the xe_validation_guard() / drm_exec_until_all_locked() loop. When
+that loop retries due to lock contention or OOM eviction
+(drm_exec_retry_on_contention() / xe_validation_retry_on_oom()),
+xe_pt_update_ops_prepare() runs again on the same vops, and each
+call to bind_op_prepare() increments current_op without resetting it.
+
+After N retries current_op exceeds the array size allocated by
+xe_vma_ops_alloc(), causing an out-of-bounds write into
+SLUB-poisoned memory and a subsequent UAF crash in
+xe_migrate_update_pgtables_cpu() when reading the corrupted pt_op->bind.
+
+Also reset needs_svm_lock and needs_invalidation which are derived in
+the same prepare pass and would otherwise cause wrong migrate ops
+selection and redundant TLB invalidation on retry.
+
+Fix this by resetting current_op, needs_svm_lock and needs_invalidation
+in xe_pt_update_ops_init().
+
+v2 (Matt):
+   - Add details in commit message.
+   - Add Fixes tag and Cc to stable@vger.kernel.org
+
+Fixes: e8babb280b5e ("drm/xe: Convert multiple bind ops into single job")
+Suggested-by: Matthew Auld <matthew.auld@intel.com>
+Cc: stable@vger.kernel.org
+Assisted-by: GitHub-Copilot:claude-sonnet-4.6
+Signed-off-by: Zongyao Bai <zongyao.bai@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20260714232433.2737533-1-zongyao.bai@intel.com
+(cherry picked from commit 046045543e530605c441063535e7dca0075369a6)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_pt.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/xe/xe_pt.c
++++ b/drivers/gpu/drm/xe/xe_pt.c
+@@ -2364,8 +2364,11 @@ static void
+ xe_pt_update_ops_init(struct xe_vm_pgtable_update_ops *pt_update_ops)
+ {
+       init_llist_head(&pt_update_ops->deferred);
++      pt_update_ops->current_op = 0;
+       pt_update_ops->start = ~0x0ull;
+       pt_update_ops->last = 0x0ull;
++      pt_update_ops->needs_svm_lock = false;
++      pt_update_ops->needs_invalidation = false;
+       xe_page_reclaim_list_init(&pt_update_ops->prl);
+ }
diff --git a/queue-7.1/drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch b/queue-7.1/drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch
new file mode 100644 (file)
index 0000000..6343848
--- /dev/null
@@ -0,0 +1,73 @@
+From 7bc597ce74bab4153b2009c92eccf889e9d74044 Mon Sep 17 00:00:00 2001
+From: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Date: Wed, 24 Jun 2026 23:19:44 +0530
+Subject: drm/xe/vm: Fix BO prefetch with CONSULT_MEM_ADVISE_PREF_LOC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+
+commit 7bc597ce74bab4153b2009c92eccf889e9d74044 upstream.
+
+When prefetch region is DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC for a BO VMA,
+the code used it as an index into region_to_mem_type[], causing an
+out-of-bounds access since the value is -1.
+
+Resolve the preferred location for BO VMAs directly: local VRAM on dGFX
+(using the BO's tile placement) or system memory on iGPU.
+
+Discovered using AI-assisted static analysis confirmed by Intel Product
+Security.
+
+v2:
+-Fix null dereference
+
+Reported-by: Martin Hodo <martin.hodo@intel.com>
+Fixes: c1bb69a2e8e2 ("drm/xe/svm: Consult madvise preferred location in prefetch")
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20260624174943.2808767-2-himal.prasad.ghimiray@intel.com
+Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+(cherry picked from commit d9a4906ac03be9f6ed3f3b45c56c866b867fd75b)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_vm.c |   25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -3256,11 +3256,26 @@ static int op_lock_and_prep(struct drm_e
+                                                   .request_decompress = false,
+                                                   .check_purged = true,
+                                           });
+-              if (!err && !xe_vma_has_no_bo(vma))
+-                      err = xe_bo_migrate(xe_vma_bo(vma),
+-                                          region_to_mem_type[region],
+-                                          NULL,
+-                                          exec);
++              if (!err && !xe_vma_has_no_bo(vma)) {
++                      struct xe_bo *bo = xe_vma_bo(vma);
++                      u32 mem_type;
++
++                      if (region == DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC) {
++                              unsigned int i;
++
++                              mem_type = XE_PL_TT;
++                              for (i = 0; i < bo->placement.num_placement; i++) {
++                                      if (mem_type_is_vram(bo->placements[i].mem_type)) {
++                                              mem_type = bo->placements[i].mem_type;
++                                              break;
++                                      }
++                              }
++                      } else {
++                              mem_type = region_to_mem_type[region];
++                      }
++
++                      err = xe_bo_migrate(bo, mem_type, NULL, exec);
++              }
+               break;
+       }
+       default:
index cf959b3d9fb4665709fdedf24bcf23cb4ed82e5c..e94fe4ab42389425e4b9912f2c18392a0965fb60 100644 (file)
@@ -403,3 +403,18 @@ drm-xe-oa-fix-offset-alignment-for-mert-whitelist_oa_mert_mmio_trg.patch
 drm-xe-rtp-add-ring_force_to_nonpriv_deny-to-oa-whitelists.patch
 drm-xe-fix-pte-index-in-xe_vm_populate_pgtable-for-chunked-binds.patch
 drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch
+drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch
+drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch
+drm-xe-nvm-fix-writable-override-for-cri.patch
+drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch
+drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch
+drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch
+drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch
+drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch
+drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch
+drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch
+drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch
+drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch
+drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch
+drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch
+drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch