static void __guc_reset_context(struct intel_context *ce, bool stalled)
 {
        struct i915_request *rq;
+       unsigned long flags;
        u32 head;
+       bool skip = false;
 
        intel_context_get(ce);
 
        /*
-        * GuC will implicitly mark the context as non-schedulable
-        * when it sends the reset notification. Make sure our state
-        * reflects this change. The context will be marked enabled
-        * on resubmission.
+        * GuC will implicitly mark the context as non-schedulable when it sends
+        * the reset notification. Make sure our state reflects this change. The
+        * context will be marked enabled on resubmission.
+        *
+        * XXX: If the context is reset as a result of the request cancellation
+        * this G2H is received after the schedule disable complete G2H which is
+        * wrong as this creates a race between the request cancellation code
+        * re-submitting the context and this G2H handler. This is a bug in the
+        * GuC but can be worked around in the meantime but converting this to a
+        * NOP if a pending enable is in flight as this indicates that a request
+        * cancellation has occurred.
         */
-       clr_context_enabled(ce);
+       spin_lock_irqsave(&ce->guc_state.lock, flags);
+       if (likely(!context_pending_enable(ce)))
+               clr_context_enabled(ce);
+       else
+               skip = true;
+       spin_unlock_irqrestore(&ce->guc_state.lock, flags);
+       if (unlikely(skip))
+               goto out_put;
 
        rq = intel_context_find_active_request(ce);
        if (!rq) {
 out_replay:
        guc_reset_state(ce, head, stalled);
        __unwind_incomplete_requests(ce);
+out_put:
        intel_context_put(ce);
 }
 
                        guc_reset_state(ce, intel_ring_wrap(ce->ring, rq->head),
                                        true);
                }
+
+               /*
+                * XXX: Racey if context is reset, see comment in
+                * __guc_reset_context().
+                */
+               flush_work(&ce_to_guc(ce)->ct.requests.worker);
+
                guc_context_unblock(ce);
        }
 }
 {
        trace_intel_context_reset(ce);
 
-       if (likely(!intel_context_is_banned(ce))) {
+       /*
+        * XXX: Racey if request cancellation has occurred, see comment in
+        * __guc_reset_context().
+        */
+       if (likely(!intel_context_is_banned(ce) &&
+                  !context_blocked(ce))) {
                capture_error_state(guc, ce);
                guc_context_replay(ce);
        }