drm/i915/guc: Don't GEM_BUG_ON on corrupted H2G CTB
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Mon, 20 Jan 2020 19:18:17 +0000 (19:18 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 24 Jan 2020 21:08:24 +0000 (21:08 +0000)
We should never BUG_ON on any corruption in CTB descriptor as
data there can be also modified by the GuC. Instead we can
use flag "is_in_error" to indicate that we will not process
any further messages over this CTB (until reset).

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200120191817.50164-1-michal.wajdeczko@intel.com
drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

index 02b5433..d848126 100644 (file)
@@ -317,18 +317,25 @@ static int ct_write(struct intel_guc_ct *ct,
 {
        struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_SEND];
        struct guc_ct_buffer_desc *desc = ctb->desc;
-       u32 head = desc->head / 4;      /* in dwords */
-       u32 tail = desc->tail / 4;      /* in dwords */
-       u32 size = desc->size / 4;      /* in dwords */
-       u32 used;                       /* in dwords */
+       u32 head = desc->head;
+       u32 tail = desc->tail;
+       u32 size = desc->size;
+       u32 used;
        u32 header;
        u32 *cmds = ctb->cmds;
        unsigned int i;
 
-       GEM_BUG_ON(desc->size % 4);
-       GEM_BUG_ON(desc->head % 4);
-       GEM_BUG_ON(desc->tail % 4);
-       GEM_BUG_ON(tail >= size);
+       if (unlikely(desc->is_in_error))
+               return -EPIPE;
+
+       if (unlikely(!IS_ALIGNED(head | tail | size, 4) ||
+                    (tail | head) >= size))
+               goto corrupted;
+
+       /* later calculations will be done in dwords */
+       head /= 4;
+       tail /= 4;
+       size /= 4;
 
        /*
         * tail == head condition indicates empty. GuC FW does not support
@@ -367,12 +374,17 @@ static int ct_write(struct intel_guc_ct *ct,
                cmds[tail] = action[i];
                tail = (tail + 1) % size;
        }
+       GEM_BUG_ON(tail > size);
 
        /* now update desc tail (back in bytes) */
        desc->tail = tail * 4;
-       GEM_BUG_ON(desc->tail > desc->size);
-
        return 0;
+
+corrupted:
+       CT_ERROR(ct, "Corrupted descriptor addr=%#x head=%u tail=%u size=%u\n",
+                desc->addr, desc->head, desc->tail, desc->size);
+       desc->is_in_error = 1;
+       return -EPIPE;
 }
 
 /**