return 0;
 }
 
+static u32 preparser_disable(bool state)
+{
+       return MI_ARB_CHECK | 1 << 8 | state;
+}
+
+static int gen12_emit_flush_render(struct i915_request *request,
+                                  u32 mode)
+{
+       const u32 scratch_addr =
+               intel_gt_scratch_offset(request->engine->gt,
+                                       INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
+
+       if (mode & EMIT_FLUSH) {
+               u32 flags = 0;
+               u32 *cs;
+
+               flags |= PIPE_CONTROL_TILE_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
+
+               flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+               flags |= PIPE_CONTROL_QW_WRITE;
+
+               flags |= PIPE_CONTROL_CS_STALL;
+
+               cs = intel_ring_begin(request, 6);
+               if (IS_ERR(cs))
+                       return PTR_ERR(cs);
+
+               cs = gen8_emit_pipe_control(cs, flags, scratch_addr);
+               intel_ring_advance(request, cs);
+       }
+
+       if (mode & EMIT_INVALIDATE) {
+               u32 flags = 0;
+               u32 *cs;
+
+               flags |= PIPE_CONTROL_COMMAND_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_TLB_INVALIDATE;
+               flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+
+               flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+               flags |= PIPE_CONTROL_QW_WRITE;
+
+               flags |= PIPE_CONTROL_CS_STALL;
+
+               cs = intel_ring_begin(request, 8);
+               if (IS_ERR(cs))
+                       return PTR_ERR(cs);
+
+               /*
+                * Prevent the pre-parser from skipping past the TLB
+                * invalidate and loading a stale page for the batch
+                * buffer / request payload.
+                */
+               *cs++ = preparser_disable(true);
+
+               cs = gen8_emit_pipe_control(cs, flags, scratch_addr);
+
+               *cs++ = preparser_disable(false);
+               intel_ring_advance(request, cs);
+       }
+
+       return 0;
+}
+
 /*
  * Reserve space for 2 NOOPs at the end of each request to be
  * used as a workaround for not being allowed to do lite
 {
        switch (INTEL_GEN(engine->i915)) {
        case 12:
-               engine->emit_flush = gen11_emit_flush_render;
+               engine->emit_flush = gen12_emit_flush_render;
                engine->emit_fini_breadcrumb = gen12_emit_fini_breadcrumb_rcs;
                break;
        case 11: