clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
 }
 
+static void reset_csb_pointers(struct intel_engine_execlists *execlists)
+{
+       /*
+        * After a reset, the HW starts writing into CSB entry [0]. We
+        * therefore have to set our HEAD pointer back one entry so that
+        * the *first* entry we check is entry 0. To complicate this further,
+        * as we don't wait for the first interrupt after reset, we have to
+        * fake the HW write to point back to the last entry so that our
+        * inline comparison of our cached head position against the last HW
+        * write works even before the first interrupt.
+        */
+       execlists->csb_head = execlists->csb_write_reset;
+       WRITE_ONCE(*execlists->csb_write, execlists->csb_write_reset);
+}
+
 static void execlists_cancel_requests(struct intel_engine_cs *engine)
 {
        struct intel_engine_execlists * const execlists = &engine->execlists;
        __unwind_incomplete_requests(engine);
 
        /* Following the reset, we need to reload the CSB read/write pointers */
-       engine->execlists.csb_head = GEN8_CSB_ENTRIES - 1;
+       reset_csb_pointers(&engine->execlists);
 
        spin_unlock_irqrestore(&engine->timeline.lock, flags);
 
                        upper_32_bits(ce->lrc_desc);
        }
 
-       execlists->csb_head = GEN8_CSB_ENTRIES - 1;
        execlists->csb_read =
                i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine));
        if (csb_force_mmio(i915)) {
                        (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0)));
 
                execlists->csb_write = (u32 __force *)execlists->csb_read;
+               execlists->csb_write_reset =
+                       _MASKED_FIELD(GEN8_CSB_WRITE_PTR_MASK,
+                                     GEN8_CSB_ENTRIES - 1);
        } else {
                execlists->csb_status =
                        &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX];
 
                execlists->csb_write =
                        &engine->status_page.page_addr[intel_hws_csb_write_index(i915)];
+               execlists->csb_write_reset = GEN8_CSB_ENTRIES - 1;
        }
+       reset_csb_pointers(execlists);
 
        return 0;