From: Greg Kroah-Hartman Date: Wed, 29 Jul 2026 11:14:50 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches 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 --- 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 index 0000000000..a6a8670ddf --- /dev/null +++ b/queue-7.1/drm-amdkfd-check-bounds-in-allocate_event_notification_slot.patch @@ -0,0 +1,44 @@ +From bb52249fbbe948875155ccd45cd8d74bf4ae747b Mon Sep 17 00:00:00 2001 +From: David Francis +Date: Thu, 21 May 2026 09:18:59 -0400 +Subject: drm/amdkfd: Check bounds in allocate_event_notification_slot + +From: David Francis + +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 +Reviewed-by: David Yat Sin +Signed-off-by: Alex Deucher +(cherry picked from commit 6853f1f6cbbeb3f53ebbbd7286536aeb2c5d5f50) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..29e977401c --- /dev/null +++ b/queue-7.1/drm-amdkfd-check-bounds-on-criu-restore-queue-type-and-mqd-size.patch @@ -0,0 +1,109 @@ +From 47ea05f246bebc81c7796f56265cffd812cf0601 Mon Sep 17 00:00:00 2001 +From: David Francis +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 + +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 +Signed-off-by: David Francis +Signed-off-by: Alex Deucher +(cherry picked from commit f19d8086f6644083c913d70bfdeee20e1b6f46a5) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..335d9bc3f0 --- /dev/null +++ b/queue-7.1/drm-amdkfd-clamp-v9-criu-control-stack-checkpoint-copy-to-bo-size.patch @@ -0,0 +1,117 @@ +From 426ffae6ecc7ec77d32bf8be065c21a1b881b084 Mon Sep 17 00:00:00 2001 +From: Yongqiang Sun +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 + +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 +Reviewed-by: David Francis +Signed-off-by: Alex Deucher +(cherry picked from commit 6c2abd0ec09e86c6323010673766f76050e28aa3) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #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 index 0000000000..46c0890aad --- /dev/null +++ b/queue-7.1/drm-amdkfd-fix-32-bit-overflow-in-cwsr-total-size-calculation.patch @@ -0,0 +1,89 @@ +From 2b0386d4293920e690c0e017708f999b93cc729b Mon Sep 17 00:00:00 2001 +From: Yongqiang Sun +Date: Mon, 6 Jul 2026 15:15:07 -0400 +Subject: drm/amdkfd: fix 32-bit overflow in CWSR total size calculation + +From: Yongqiang Sun + +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 +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +(cherry picked from commit 319f7e13423ae3f486b9aea82f9ad2d6af0ee608) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include + #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 index 0000000000..658486d837 --- /dev/null +++ b/queue-7.1/drm-amdkfd-free-mqd-managers-on-dqm-init-failures.patch @@ -0,0 +1,56 @@ +From b240f792ae02e9b687eafff934a39e57d1e45365 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Wed, 8 Jul 2026 18:51:15 +0800 +Subject: drm/amdkfd: free MQD managers on DQM init failures + +From: Guangshuo Li + +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 +Reviewed-by: Mukul Joshi +Reviewed-by: Felix Kuehling +Signed-off-by: Felix Kuehling +Signed-off-by: Alex Deucher +(cherry picked from commit 1fff2e07b6670bc5b8f7344a8708c136259cb176) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..b70544b640 --- /dev/null +++ b/queue-7.1/drm-amdkfd-guard-m-cp_hqd_eop_control-setting-by-q-eop_ring_buffer_size.patch @@ -0,0 +1,90 @@ +From 8cd2ea7bab77b7aa087b1a6cc26d2df03c2a6ed9 Mon Sep 17 00:00:00 2001 +From: Xiaogang Chen +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 + +commit 8cd2ea7bab77b7aa087b1a6cc26d2df03c2a6ed9 upstream. + +To avoid wraparound if the value is 0. + +Signed-off-by: Xiaogang Chen +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit c0cae35661868af207077a4306bc42c7c972947c) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..ede0fcd559 --- /dev/null +++ b/queue-7.1/drm-amdkfd-use-kvcalloc-to-allocate-arrays.patch @@ -0,0 +1,74 @@ +From 9c8b85f95c1d4736b967e17b8eb4a463c055bea3 Mon Sep 17 00:00:00 2001 +From: David Francis +Date: Thu, 25 Jun 2026 10:09:13 -0400 +Subject: drm/amdkfd: Use kvcalloc to allocate arrays + +From: David Francis + +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 +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 60b048c93f7a3add39757ad65fe2bb6e58eeae23) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..8699859bc3 --- /dev/null +++ b/queue-7.1/drm-imagination-acquire-vm_ctx-lock-before-mapping-memory-to-gpu-vm.patch @@ -0,0 +1,67 @@ +From 17e2030f37600994440f875dc410615d5c66ee6d Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +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 + +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 + +[] drm_gpuva_find+0x28/0x6c [drm_gpuvm] +[] pvr_vm_unmap+0x34/0x68 [powervr] +[] pvr_ioctl_vm_unmap+0x2e/0x50 [powervr] +[] drm_ioctl_kernel+0x8e/0xdc +[] drm_ioctl+0x1be/0x3e0 +[] __riscv_sys_ioctl+0xba/0xc4 +[] do_trap_ecall_u+0x23e/0x3f4 +[] 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 +Reviewed-by: Alessio Belle +Link: https://patch.msgid.link/20260714073641.1935075-1-zhengxingda@iscas.ac.cn +Signed-off-by: Alessio Belle +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d05253d06e --- /dev/null +++ b/queue-7.1/drm-imagination-fix-double-call-to-drm_sched_entity_fini.patch @@ -0,0 +1,180 @@ +From 4af24c27a39ba147a613a09e10b9e0f7294524c0 Mon Sep 17 00:00:00 2001 +From: Brajesh Gupta +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 + +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 +Reviewed-by: Alessio Belle +Link: https://patch.msgid.link/20260630-b4-sched_fix-v7-1-71aa39c62627@imgtec.com +Signed-off-by: Alessio Belle +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d7c4a21c27 --- /dev/null +++ b/queue-7.1/drm-imagination-fix-error-checking-of-pvr_vm_context_lookup.patch @@ -0,0 +1,87 @@ +From cf385cf6e713eba0720651174dac0b2d2f5bb8f8 Mon Sep 17 00:00:00 2001 +From: Luigi Santivetti +Date: Tue, 7 Jul 2026 16:17:16 +0100 +Subject: drm/imagination: fix error checking of pvr_vm_context_lookup() + +From: Luigi Santivetti + +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 +Reviewed-by: Alessio Belle +Link: https://patch.msgid.link/20260707-staging-ddkopsrc-2435-v1-1-24e160d44476@imgtec.com +Signed-off-by: Alessio Belle +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..c422671154 --- /dev/null +++ b/queue-7.1/drm-imagination-fix-user-array-stride-in-pvr_set_uobj_array.patch @@ -0,0 +1,59 @@ +From 8dc8f3f4c2382fb7d1b1986ba8f33a2466cd3d7a Mon Sep 17 00:00:00 2001 +From: Shuvam Pandey +Date: Wed, 1 Jul 2026 11:44:34 -0700 +Subject: drm/imagination: Fix user array stride in pvr_set_uobj_array() + +From: Shuvam Pandey + +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 +Signed-off-by: Shuvam Pandey +Link: https://patch.msgid.link/6a456012.eb165e5c.113c2a.b71d@mx.google.com +Signed-off-by: Alessio Belle +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + } + diff --git a/queue-7.1/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch b/queue-7.1/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch index f575d7ac8a..352f336795 100644 --- a/queue-7.1/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch +++ b/queue-7.1/drm-xe-hold-a-dma-buf-reference-for-imported-bos.patch @@ -96,17 +96,15 @@ Link: https://patch.msgid.link/20260710191027.260160-2-nitin.r.gote@intel.com Signed-off-by: Thomas Hellström Signed-off-by: Greg Kroah-Hartman --- - 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 index 0000000000..577d90e1a3 --- /dev/null +++ b/queue-7.1/drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch @@ -0,0 +1,80 @@ +From 57441577bac3637473da2c9644336eaa0ac5732f Mon Sep 17 00:00:00 2001 +From: Arvind Yadav +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 + +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 +Cc: Matthew Brost +Cc: Thomas Hellström +Cc: Himal Prasad Ghimiray +Signed-off-by: Arvind Yadav +Reviewed-by: Himal Prasad Ghimiray +Link: https://patch.msgid.link/20260526135447.2973029-1-arvind.yadav@intel.com +Signed-off-by: Tejas Upadhyay +Fixes: ada7486c5668 ("drm/xe: Implement madvise ioctl for xe") +Cc: # v6.18+ +(cherry picked from commit 134377098b9c14abd31c3bcac00c9653f0f0c4c3) +Signed-off-by: Thomas Hellström +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..2e237b0503 --- /dev/null +++ b/queue-7.1/drm-xe-nvm-fix-writable-override-for-cri.patch @@ -0,0 +1,79 @@ +From c473761f8178760b915633332908409c73bfdb9e Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +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 + +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 +Reviewed-by: Rodrigo Vivi +Link: https://patch.msgid.link/20260714-cri_nvm_fdo_flip-v2-1-14580e71b58e@intel.com +Signed-off-by: Rodrigo Vivi +(cherry picked from commit 2007be18d2318a59748da5da1b8968042213d5f1) +Signed-off-by: Thomas Hellström +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..7218a32367 --- /dev/null +++ b/queue-7.1/drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch @@ -0,0 +1,65 @@ +From 6384271ac1ac0099198d15df79212a19ebdb929d Mon Sep 17 00:00:00 2001 +From: Zongyao Bai +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 + +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 +Cc: stable@vger.kernel.org +Assisted-by: GitHub-Copilot:claude-sonnet-4.6 +Signed-off-by: Zongyao Bai +Reviewed-by: Matthew Brost +Signed-off-by: Matthew Brost +Link: https://patch.msgid.link/20260714232433.2737533-1-zongyao.bai@intel.com +(cherry picked from commit 046045543e530605c441063535e7dca0075369a6) +Signed-off-by: Thomas Hellström +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..6343848233 --- /dev/null +++ b/queue-7.1/drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch @@ -0,0 +1,73 @@ +From 7bc597ce74bab4153b2009c92eccf889e9d74044 Mon Sep 17 00:00:00 2001 +From: Himal Prasad Ghimiray +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 + +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 +Fixes: c1bb69a2e8e2 ("drm/xe/svm: Consult madvise preferred location in prefetch") +Cc: Matthew Brost +Cc: stable@vger.kernel.org +Reviewed-by: Matthew Brost +Link: https://patchwork.freedesktop.org/patch/msgid/20260624174943.2808767-2-himal.prasad.ghimiray@intel.com +Signed-off-by: Himal Prasad Ghimiray +(cherry picked from commit d9a4906ac03be9f6ed3f3b45c56c866b867fd75b) +Signed-off-by: Thomas Hellström +Signed-off-by: Greg Kroah-Hartman +--- + 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: diff --git a/queue-7.1/series b/queue-7.1/series index cf959b3d9f..e94fe4ab42 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -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