[PATCH] drm/i915/gvt: Check engine id before using it
Tina Zhang
tina.zhang at intel.com
Wed Mar 18 06:26:35 UTC 2020
The number of engines is I915_NUM_ENGINES. Since the array starts from
zero, the last one's index in the array should be (I915_NUM_ENGINES - 1).
Directly using engined->id as the index of the array, may lead to out of
array's range issue.
Klocwork detected this issue and this patch solves it by checking
engine->id before using it.
Signed-off-by: Tina Zhang <tina.zhang at intel.com>
---
drivers/gpu/drm/i915/gvt/execlist.c | 19 ++++++++++++++++---
drivers/gpu/drm/i915/gvt/handlers.c | 7 ++++---
drivers/gpu/drm/i915/gvt/scheduler.c | 19 +++++++++++++++----
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index dd25c3024370..37f8fcac7b05 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -437,6 +437,9 @@ static int submit_context(struct intel_vgpu *vgpu,
struct intel_vgpu_submission *s = &vgpu->submission;
struct intel_vgpu_workload *workload = NULL;
+ if (!engine || engine->id >= I915_NUM_ENGINES)
+ return -EINVAL;
+
workload = intel_vgpu_create_workload(vgpu, engine, desc);
if (IS_ERR(workload))
return PTR_ERR(workload);
@@ -459,10 +462,15 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine)
{
struct intel_vgpu_submission *s = &vgpu->submission;
- struct intel_vgpu_execlist *execlist = &s->execlist[engine->id];
+ struct intel_vgpu_execlist *execlist;
struct execlist_ctx_descriptor_format *desc[2];
int i, ret;
+ if (!engine || engine->id >= I915_NUM_ENGINES)
+ return -EINVAL;
+
+ execlist = &s->execlist[engine->id];
+
desc[0] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 0);
desc[1] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 1);
@@ -503,11 +511,16 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu,
const struct intel_engine_cs *engine)
{
struct intel_vgpu_submission *s = &vgpu->submission;
- struct intel_vgpu_execlist *execlist = &s->execlist[engine->id];
+ struct intel_vgpu_execlist *execlist;
struct execlist_context_status_pointer_format ctx_status_ptr;
u32 ctx_status_ptr_reg;
- memset(execlist, 0, sizeof(*execlist));
+ if (!engine || engine->id >= I915_NUM_ENGINES)
+ return;
+
+ execlist = &s->execlist[engine->id];
+
+ memset(execlist, 0, sizeof(struct intel_vgpu_execlist));
execlist->vgpu = vgpu;
execlist->engine = engine;
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 0182e2a5acff..f11908a28ce7 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -1690,7 +1690,8 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
u32 data = *(u32 *)p_data;
int ret = 0;
- if (drm_WARN_ON(&i915->drm, !engine))
+ if (drm_WARN_ON(&i915->drm, !engine) ||
+ engine->id >= I915_NUM_ENGINES)
return -EINVAL;
execlist = &vgpu->submission.execlist[engine->id];
@@ -1743,8 +1744,8 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST);
return 0;
}
- if ((data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE))
- || (data & _MASKED_BIT_DISABLE(GFX_RUN_LIST_ENABLE))) {
+ if (engine && ((data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE))
+ || (data & _MASKED_BIT_DISABLE(GFX_RUN_LIST_ENABLE)))) {
enable_execlist = !!(data & GFX_RUN_LIST_ENABLE);
gvt_dbg_core("EXECLIST %s on ring %s\n",
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 1c95bf8cbed0..8436984cd1f6 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -232,13 +232,21 @@ static int shadow_context_status_change(struct notifier_block *nb,
unsigned long action, void *data)
{
struct i915_request *rq = data;
- struct intel_gvt *gvt = container_of(nb, struct intel_gvt,
- shadow_ctx_notifier_block[rq->engine->id]);
- struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
- enum intel_engine_id ring_id = rq->engine->id;
+ struct intel_gvt *gvt;
+ struct intel_gvt_workload_scheduler *scheduler;
+ enum intel_engine_id ring_id;
struct intel_vgpu_workload *workload;
unsigned long flags;
+ if (!rq || !rq->engine || rq->engine->id >= I915_NUM_ENGINES)
+ return NOTIFY_OK;
+
+ ring_id = rq->engine->id;
+
+ gvt = container_of(nb, struct intel_gvt,
+ shadow_ctx_notifier_block[rq->engine->id]);
+ scheduler = &gvt->scheduler;
+
if (!is_gvt_request(rq)) {
spin_lock_irqsave(&scheduler->mmio_context_lock, flags);
if (action == INTEL_CONTEXT_SCHEDULE_IN &&
@@ -1586,6 +1594,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu,
*/
void intel_vgpu_queue_workload(struct intel_vgpu_workload *workload)
{
+ if (workload->engine->id >= I915_NUM_ENGINES)
+ return;
+
list_add_tail(&workload->list,
workload_q_head(workload->vgpu, workload->engine));
intel_gvt_kick_schedule(workload->vgpu->gvt);
--
2.17.1
More information about the intel-gvt-dev
mailing list