* [PATCH] accel/ivpu: Add support for getting and setting command queue priority
@ 2026-08-31 12:16 Andrzej Kacprowski
2026-08-31 12:33 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Andrzej Kacprowski @ 2026-08-31 12:16 UTC (permalink / raw)
To: dri-devel
Cc: oded.gabbay, jeff.hugo, karol.wachowski, lizhi.hou,
andrzej.kacprowski, dawid.osuchowski
Add a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and update
the scheduling priority of an existing command queue, identified by
its ID via drm_ivpu_param.index.
The priority can be changed on a queue that already has pending jobs;
if the queue's doorbell is registered, the new priority is propagated
to the firmware immediately, otherwise it is applied when the queue is
next registered. The firmware picks up the change at the first
opportunity.
The feature requires HW scheduling mode and is advertised through the
new DRM_IVPU_CAP_CMDQ_SET_PRIORITY capability. Legacy command queues
are not supported.
Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
---
drivers/accel/ivpu/ivpu_drv.c | 13 ++++++
drivers/accel/ivpu/ivpu_job.c | 85 +++++++++++++++++++++++++++++++++++
drivers/accel/ivpu/ivpu_job.h | 5 ++-
include/uapi/drm/ivpu_accel.h | 17 ++++++-
4 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 95120957f42a..0f215392d42d 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -205,6 +205,7 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32 capability)
case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR:
return true;
case DRM_IVPU_CAP_MANAGE_CMDQ:
+ case DRM_IVPU_CAP_CMDQ_SET_PRIORITY:
return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW;
default:
return false;
@@ -273,6 +274,9 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
args->value = ivpu_fw_preempt_buf_size(vdev);
break;
+ case DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ ret = ivpu_cmdq_get_priority(file_priv, args->index, &args->value);
+ break;
default:
ret = -EINVAL;
break;
@@ -284,14 +288,23 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
+ struct ivpu_file_priv *file_priv = file->driver_priv;
struct drm_ivpu_param *args = data;
int ret = 0;
+ int idx;
+
+ if (!drm_dev_enter(dev, &idx))
+ return -ENODEV;
switch (args->param) {
+ case DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ ret = ivpu_cmdq_set_priority(file_priv, args->index, args->value);
+ break;
default:
ret = -EINVAL;
}
+ drm_dev_exit(idx);
return ret;
}
diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
index ebb2c865b09a..b3de5dd29d1e 100644
--- a/drivers/accel/ivpu/ivpu_job.c
+++ b/drivers/accel/ivpu/ivpu_job.c
@@ -323,6 +323,11 @@ static inline u8 ivpu_job_to_jsm_priority(u8 priority)
return priority - 1;
}
+static inline u8 ivpu_jsm_to_job_priority(u8 priority)
+{
+ return priority + 1;
+}
+
static void ivpu_cmdq_destroy(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
{
lockdep_assert_held(&file_priv->lock);
@@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
return ret;
}
+static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
+{
+ if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
+ ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
+ return -ENODEV;
+ }
+
+ if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
+ ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
+ return -EINVAL;
+ }
+
+ if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
+ return -EINVAL;
+
+ return 0;
+}
+
+int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_cmdq *cmdq;
+ int ret;
+
+ ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, DRM_IVPU_JOB_PRIORITY_NORMAL);
+ if (ret)
+ return ret;
+
+ guard(mutex)(&file_priv->lock);
+
+ cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
+ if (!cmdq || cmdq->is_legacy)
+ return -EINVAL;
+
+ *priority = ivpu_jsm_to_job_priority(cmdq->priority);
+ return 0;
+}
+
+int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_cmdq *cmdq;
+ u8 jsm_priority;
+ int ret = 0;
+
+ ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, priority);
+ if (ret)
+ return ret;
+
+ ret = ivpu_rpm_get(vdev);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&file_priv->lock);
+
+ cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
+ if (!cmdq || cmdq->is_legacy) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ jsm_priority = ivpu_job_to_jsm_priority(priority);
+ if (cmdq->priority == jsm_priority)
+ goto out;
+
+ if (cmdq->db_id) {
+ ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq_id,
+ jsm_priority);
+ if (ret)
+ goto out;
+ }
+
+ cmdq->priority = jsm_priority;
+
+out:
+ mutex_unlock(&file_priv->lock);
+ ivpu_rpm_put(vdev);
+ return ret;
+}
+
static void
ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
struct vpu_jsm_msg *jsm_msg)
diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h
index d8dbce82447a..6e32fea1eb62 100644
--- a/drivers/accel/ivpu/ivpu_job.h
+++ b/drivers/accel/ivpu/ivpu_job.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2025 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#ifndef __IVPU_JOB_H__
@@ -81,6 +81,9 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *
int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority);
+int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority);
+
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h
index 264505d54f93..9ce19d9c3131 100644
--- a/include/uapi/drm/ivpu_accel.h
+++ b/include/uapi/drm/ivpu_accel.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
- * Copyright (C) 2020-2025 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#ifndef __UAPI_IVPU_DRM_H__
@@ -96,6 +96,7 @@ extern "C" {
#define DRM_IVPU_PARAM_SKU 12
#define DRM_IVPU_PARAM_CAPABILITIES 13
#define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14
+#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15
#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
@@ -140,6 +141,15 @@ extern "C" {
*/
#define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4
+/**
+ * DRM_IVPU_CAP_CMDQ_SET_PRIORITY
+ *
+ * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set command
+ * queue priority.
+ * This allows changing command queue priority after creation.
+ */
+#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5
+
/**
* struct drm_ivpu_param - Get/Set VPU parameters
*/
@@ -192,6 +202,11 @@ struct drm_ivpu_param {
*
* %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
* Size of the preemption buffer (read-only)
+ *
+ * %DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*).
+ * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as DRM_IVPU_JOB_PRIORITY_NORMAL.
+ * Command queue ID is given via drm_ivpu_param.index.
*/
__u32 param;
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] accel/ivpu: Add support for getting and setting command queue priority
2026-08-31 12:16 [PATCH] accel/ivpu: Add support for getting and setting command queue priority Andrzej Kacprowski
@ 2026-08-31 12:33 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-08-31 12:33 UTC (permalink / raw)
To: Andrzej Kacprowski; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing CAP_SYS_NICE or DRM_MASTER check for elevated job priorities (REALTIME / FOCUS), allowing unprivileged users to monopolize the NPU.
--
commit 57cf0d7005a7761ad6193ea568802164b7fac6db
Author: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
accel/ivpu: Add support for getting and setting command queue priority
This commit adds a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and
update the scheduling priority of an existing command queue. The priority
can be changed on a queue that already has pending jobs, propagating the
change to firmware in hardware scheduling mode.
> diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
> index ebb2c865b09a0..b3de5dd29d1e8 100644
> --- a/drivers/accel/ivpu/ivpu_job.c
> +++ b/drivers/accel/ivpu/ivpu_job.c
[ ... ]
> @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
> return ret;
> }
>
> +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
> +{
> + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
> + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
> + return -ENODEV;
> + }
> +
> + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
> + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
> + return -EINVAL;
> + }
> +
> + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
> + return -EINVAL;
[Severity: High]
This is a pre-existing issue, but is there a missing capability check for
elevated priorities here?
An unprivileged user who opens the NPU device can call the IVPU_SET_PARAM
ioctl with DRM_IVPU_PARAM_CMDQ_PRIORITY and set the priority to
DRM_IVPU_JOB_PRIORITY_REALTIME. Without a CAP_SYS_NICE or DRM_MASTER check,
could a malicious or buggy application elevate its command queue priority to
monopolize the hardware and starve other processes?
I notice this same behavior appears to be pre-existing in
ivpu_cmdq_create_ioctl() as well, where queues can be created with realtime
priority by any user. Should these priority levels be restricted?
> +
> + return 0;
> +}
> +
> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
> +{
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260831121617.395523-1-andrzej.kacprowski@linux.intel.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-31 12:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 12:16 [PATCH] accel/ivpu: Add support for getting and setting command queue priority Andrzej Kacprowski
2026-08-31 12:33 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox