drm/i915/gvt: fix crash in vgpu_reset_execlist
authorDu, Changbin <changbin.du@intel.com>
Fri, 11 Nov 2016 08:33:06 +0000 (16:33 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Mon, 14 Nov 2016 10:06:43 +0000 (18:06 +0800)
We initiate vgpu->workload_q_head via for_each_engine
macro which may skip unavailable engines. So we should
follow this rule anywhere. The function
intel_vgpu_reset_execlist is not aware of this. Kernel
crash when touch a uninitiated vgpu->workload_q_head[x].
Let's fix it by using for_each_engine_masked and skip
unavailable engine ID. Meanwhile rename ring_bitmap to
general name engine_mask.

v2: remove unnecessary engine activation check (zhenyu)

Signed-off-by: Du, Changbin <changbin.du@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/execlist.c
drivers/gpu/drm/i915/gvt/execlist.h

index c1f6019d889572938f1019f78078654f41958d98..f32bb6f6495ce0aafddf35d920298c5d315af9bc 100644 (file)
@@ -838,23 +838,21 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu)
 }
 
 void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
-               unsigned long ring_bitmap)
+               unsigned long engine_mask)
 {
-       int bit;
-       struct list_head *pos, *n;
-       struct intel_vgpu_workload *workload = NULL;
+       struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+       struct intel_engine_cs *engine;
+       struct intel_vgpu_workload *pos, *n;
+       unsigned int tmp;
 
-       for_each_set_bit(bit, &ring_bitmap, sizeof(ring_bitmap) * 8) {
-               if (bit >= I915_NUM_ENGINES)
-                       break;
+       for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
                /* free the unsubmited workload in the queue */
-               list_for_each_safe(pos, n, &vgpu->workload_q_head[bit]) {
-                       workload = container_of(pos,
-                                       struct intel_vgpu_workload, list);
-                       list_del_init(&workload->list);
-                       free_workload(workload);
+               list_for_each_entry_safe(pos, n,
+                       &vgpu->workload_q_head[engine->id], list) {
+                       list_del_init(&pos->list);
+                       free_workload(pos);
                }
 
-               init_vgpu_execlist(vgpu, bit);
+               init_vgpu_execlist(vgpu, engine->id);
        }
 }
index 635f31c6dcc161bb8af01489760646edbfc174a3..7eced40a1e309fe02b564e719847b6bbf424acf9 100644 (file)
@@ -183,6 +183,6 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu);
 int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id);
 
 void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
-               unsigned long ring_bitmap);
+               unsigned long engine_mask);
 
 #endif /*_GVT_EXECLIST_H_*/