The exec ioctl allows userspace to specify an arbitrary num_syncs value. Without bounds checking, a very large num_syncs can force an excessively large allocation, leading to kernel warnings from the page allocator as below.
Introduce XE_EXEC_MAX_SYNCS (set to 64) and reject any request exceeding this limit.
" ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1217 at mm/page_alloc.c:5124 __alloc_frozen_pages_noprof+0x2f8/0x2180 mm/page_alloc.c:5124 ... Call Trace: <TASK> alloc_pages_mpol+0xe4/0x330 mm/mempolicy.c:2416 ___kmalloc_large_node+0xd8/0x110 mm/slub.c:4317 __kmalloc_large_node_noprof+0x18/0xe0 mm/slub.c:4348 __do_kmalloc_node mm/slub.c:4364 [inline] __kmalloc_noprof+0x3d4/0x4b0 mm/slub.c:4388 kmalloc_noprof include/linux/slab.h:909 [inline] kmalloc_array_noprof include/linux/slab.h:948 [inline] xe_exec_ioctl+0xa47/0x1e70 drivers/gpu/drm/xe/xe_exec.c:158 drm_ioctl_kernel+0x1f1/0x3e0 drivers/gpu/drm/drm_ioctl.c:797 drm_ioctl+0x5e7/0xc50 drivers/gpu/drm/drm_ioctl.c:894 xe_drm_ioctl+0x10b/0x170 drivers/gpu/drm/xe/xe_device.c:224 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:598 [inline] __se_sys_ioctl fs/ioctl.c:584 [inline] __x64_sys_ioctl+0x18b/0x210 fs/ioctl.c:584 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xbb/0x380 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... "
v2: Add "Reported-by" and Cc stable kernels.
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6450 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Reported-by: Koen Koning koen.koning@intel.com Reported-by: Peter Senna Tschudin peter.senna@linux.intel.com Cc: stable@vger.kernel.org Cc: Matthew Brost matthew.brost@intel.com Signed-off-by: Shuicheng Lin shuicheng.lin@intel.com --- drivers/gpu/drm/xe/xe_exec.c | 5 +++++ include/uapi/drm/xe_drm.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c index 4d81210e41f5..01c56fd95d5b 100644 --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -162,6 +162,11 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) }
if (args->num_syncs) { + if (XE_IOCTL_DBG(xe, args->num_syncs > XE_EXEC_MAX_SYNCS)) { + err = -EINVAL; + goto err_exec_queue; + } + syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL); if (!syncs) { err = -ENOMEM; diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 47853659a705..1901ca26621a 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1463,6 +1463,7 @@ struct drm_xe_exec { /** @exec_queue_id: Exec queue ID for the batch buffer */ __u32 exec_queue_id;
+#define XE_EXEC_MAX_SYNCS 64 /** @num_syncs: Amount of struct drm_xe_sync in array. */ __u32 num_syncs;
On Wed, Nov 19, 2025 at 02:42:54AM +0000, Shuicheng Lin wrote:
The exec ioctl allows userspace to specify an arbitrary num_syncs value. Without bounds checking, a very large num_syncs can force an excessively large allocation, leading to kernel warnings from the page allocator as below.
Introduce XE_EXEC_MAX_SYNCS (set to 64) and reject any request exceeding this limit.
This seems reasonable, I don't think any existing UMDs or even IGTs likely use more than 64 but I think we check if VK user facing interfaces allow more. If so, we might need something higher than 64 even though it is very unlikely use case.
" ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1217 at mm/page_alloc.c:5124 __alloc_frozen_pages_noprof+0x2f8/0x2180 mm/page_alloc.c:5124 ... Call Trace:
<TASK> alloc_pages_mpol+0xe4/0x330 mm/mempolicy.c:2416 ___kmalloc_large_node+0xd8/0x110 mm/slub.c:4317 __kmalloc_large_node_noprof+0x18/0xe0 mm/slub.c:4348 __do_kmalloc_node mm/slub.c:4364 [inline] __kmalloc_noprof+0x3d4/0x4b0 mm/slub.c:4388 kmalloc_noprof include/linux/slab.h:909 [inline] kmalloc_array_noprof include/linux/slab.h:948 [inline] xe_exec_ioctl+0xa47/0x1e70 drivers/gpu/drm/xe/xe_exec.c:158 drm_ioctl_kernel+0x1f1/0x3e0 drivers/gpu/drm/drm_ioctl.c:797 drm_ioctl+0x5e7/0xc50 drivers/gpu/drm/drm_ioctl.c:894 xe_drm_ioctl+0x10b/0x170 drivers/gpu/drm/xe/xe_device.c:224 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:598 [inline] __se_sys_ioctl fs/ioctl.c:584 [inline] __x64_sys_ioctl+0x18b/0x210 fs/ioctl.c:584 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xbb/0x380 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... "
v2: Add "Reported-by" and Cc stable kernels.
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6450 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Reported-by: Koen Koning koen.koning@intel.com Reported-by: Peter Senna Tschudin peter.senna@linux.intel.com Cc: stable@vger.kernel.org Cc: Matthew Brost matthew.brost@intel.com Signed-off-by: Shuicheng Lin shuicheng.lin@intel.com
drivers/gpu/drm/xe/xe_exec.c | 5 +++++ include/uapi/drm/xe_drm.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c index 4d81210e41f5..01c56fd95d5b 100644 --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -162,6 +162,11 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) } if (args->num_syncs) {
if (XE_IOCTL_DBG(xe, args->num_syncs > XE_EXEC_MAX_SYNCS)) {err = -EINVAL;goto err_exec_queue;}
I think OA, VM bind, and exec IOCTL should enforce the same limit if we need one.
syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL);
Another option is kvcalloc which allows large memory allocations in the kernel. I'd lean towards some reasonable limit though.
Matt
if (!syncs) { err = -ENOMEM;diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 47853659a705..1901ca26621a 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1463,6 +1463,7 @@ struct drm_xe_exec { /** @exec_queue_id: Exec queue ID for the batch buffer */ __u32 exec_queue_id; +#define XE_EXEC_MAX_SYNCS 64 /** @num_syncs: Amount of struct drm_xe_sync in array. */ __u32 num_syncs; -- 2.49.0
On 19/11/2025 05:40, Matthew Brost wrote:
On Wed, Nov 19, 2025 at 02:42:54AM +0000, Shuicheng Lin wrote:
The exec ioctl allows userspace to specify an arbitrary num_syncs value. Without bounds checking, a very large num_syncs can force an excessively large allocation, leading to kernel warnings from the page allocator as below.
Introduce XE_EXEC_MAX_SYNCS (set to 64) and reject any request exceeding this limit.
This seems reasonable, I don't think any existing UMDs or even IGTs likely use more than 64 but I think we check if VK user facing interfaces allow more. If so, we might need something higher than 64 even though it is very unlikely use case.
Yes there is dEQP-VK.synchronization.timeline_semaphore.misc.ignore_timeline_semaphore_info will use 128 (64 waits + 64 signals).
-Lionel
" ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1217 at mm/page_alloc.c:5124 __alloc_frozen_pages_noprof+0x2f8/0x2180 mm/page_alloc.c:5124 ... Call Trace:
<TASK> alloc_pages_mpol+0xe4/0x330 mm/mempolicy.c:2416 ___kmalloc_large_node+0xd8/0x110 mm/slub.c:4317 __kmalloc_large_node_noprof+0x18/0xe0 mm/slub.c:4348 __do_kmalloc_node mm/slub.c:4364 [inline] __kmalloc_noprof+0x3d4/0x4b0 mm/slub.c:4388 kmalloc_noprof include/linux/slab.h:909 [inline] kmalloc_array_noprof include/linux/slab.h:948 [inline] xe_exec_ioctl+0xa47/0x1e70 drivers/gpu/drm/xe/xe_exec.c:158 drm_ioctl_kernel+0x1f1/0x3e0 drivers/gpu/drm/drm_ioctl.c:797 drm_ioctl+0x5e7/0xc50 drivers/gpu/drm/drm_ioctl.c:894 xe_drm_ioctl+0x10b/0x170 drivers/gpu/drm/xe/xe_device.c:224 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:598 [inline] __se_sys_ioctl fs/ioctl.c:584 [inline] __x64_sys_ioctl+0x18b/0x210 fs/ioctl.c:584 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xbb/0x380 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... "
v2: Add "Reported-by" and Cc stable kernels.
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6450 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Reported-by: Koen Koning koen.koning@intel.com Reported-by: Peter Senna Tschudin peter.senna@linux.intel.com Cc: stable@vger.kernel.org Cc: Matthew Brost matthew.brost@intel.com Signed-off-by: Shuicheng Lin shuicheng.lin@intel.com
drivers/gpu/drm/xe/xe_exec.c | 5 +++++ include/uapi/drm/xe_drm.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c index 4d81210e41f5..01c56fd95d5b 100644 --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -162,6 +162,11 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) } if (args->num_syncs) {
if (XE_IOCTL_DBG(xe, args->num_syncs > XE_EXEC_MAX_SYNCS)) {err = -EINVAL;goto err_exec_queue;}I think OA, VM bind, and exec IOCTL should enforce the same limit if we need one.
syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL);Another option is kvcalloc which allows large memory allocations in the kernel. I'd lean towards some reasonable limit though.
Matt
if (!syncs) { err = -ENOMEM;diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 47853659a705..1901ca26621a 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1463,6 +1463,7 @@ struct drm_xe_exec { /** @exec_queue_id: Exec queue ID for the batch buffer */ __u32 exec_queue_id; +#define XE_EXEC_MAX_SYNCS 64 /** @num_syncs: Amount of struct drm_xe_sync in array. */ __u32 num_syncs; -- 2.49.0
linux-stable-mirror@lists.linaro.org