drm/i915/dsb: Avoid corrupting the first register write
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 6 Jun 2023 19:14:51 +0000 (22:14 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 7 Sep 2023 12:44:16 +0000 (15:44 +0300)
i915_gem_object_create_internal() does not hand out zeroed
memory. Thus we may confuse whatever stale garbage is in
there as a previous register write and mistakenly handle the
first actual register write as an indexed write. This can
end up corrupting the instruction sufficiently well to lose
the entire register write.

Make sure we've actually emitted a previous instruction before
attemting indexed register write merging.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230606191504.18099-7-ville.syrjala@linux.intel.com
Reviewed-by: Animesh Manna <animesh.manna@intel.com>
drivers/gpu/drm/i915/display/intel_dsb.c

index cdb80352b84481054a5182b57e1b8469a40f87e0..3de0d572c511a729ca74a83fd05a534eff6f158c 100644 (file)
@@ -137,6 +137,14 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb,
        const u32 *buf = dsb->cmd_buf;
        u32 prev_opcode, prev_reg;
 
+       /*
+        * Nothing emitted yet? Must check before looking
+        * at the actual data since i915_gem_object_create_internal()
+        * does *not* give you zeroed memory!
+        */
+       if (dsb->free_pos == 0)
+               return false;
+
        prev_opcode = buf[dsb->ins_start_offset + 1] >> DSB_OPCODE_SHIFT;
        prev_reg = buf[dsb->ins_start_offset + 1] & DSB_REG_VALUE_MASK;