Commit 51883883 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2023-01-12' of...

Merge tag 'drm-intel-fixes-2023-01-12' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-fixes

- Reserve enough fence slot for i915_vma_unbind_vsync (Nirmoy)
- Fix potential use after free (Rob Clark)
- Reset engines twice in case of reset failure (Chris)
- Use multi-cast registers for SVG Unit registers (Gustavo)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Y8AbHelGeXc5eQ8U@intel.com
parents 28d31e1a 58fc14e1
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -1688,6 +1688,10 @@ void i915_gem_init__contexts(struct drm_i915_private *i915)
	init_contexts(&i915->gem.contexts);
}

/*
 * Note that this implicitly consumes the ctx reference, by placing
 * the ctx in the context_xa.
 */
static void gem_context_register(struct i915_gem_context *ctx,
				 struct drm_i915_file_private *fpriv,
				 u32 id)
@@ -1703,10 +1707,6 @@ static void gem_context_register(struct i915_gem_context *ctx,
	snprintf(ctx->name, sizeof(ctx->name), "%s[%d]",
		 current->comm, pid_nr(ctx->pid));

	/* And finally expose ourselves to userspace via the idr */
	old = xa_store(&fpriv->context_xa, id, ctx, GFP_KERNEL);
	WARN_ON(old);

	spin_lock(&ctx->client->ctx_lock);
	list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list);
	spin_unlock(&ctx->client->ctx_lock);
@@ -1714,6 +1714,10 @@ static void gem_context_register(struct i915_gem_context *ctx,
	spin_lock(&i915->gem.contexts.lock);
	list_add_tail(&ctx->link, &i915->gem.contexts.list);
	spin_unlock(&i915->gem.contexts.lock);

	/* And finally expose ourselves to userspace via the idr */
	old = xa_store(&fpriv->context_xa, id, ctx, GFP_KERNEL);
	WARN_ON(old);
}

int i915_gem_context_open(struct drm_i915_private *i915,
@@ -2199,14 +2203,22 @@ finalize_create_context_locked(struct drm_i915_file_private *file_priv,
	if (IS_ERR(ctx))
		return ctx;

	/*
	 * One for the xarray and one for the caller.  We need to grab
	 * the reference *prior* to making the ctx visble to userspace
	 * in gem_context_register(), as at any point after that
	 * userspace can try to race us with another thread destroying
	 * the context under our feet.
	 */
	i915_gem_context_get(ctx);

	gem_context_register(ctx, file_priv, id);

	old = xa_erase(&file_priv->proto_context_xa, id);
	GEM_BUG_ON(old != pc);
	proto_context_close(file_priv->dev_priv, pc);

	/* One for the xarray and one for the caller */
	return i915_gem_context_get(ctx);
	return ctx;
}

struct i915_gem_context *
+2 −2
Original line number Diff line number Diff line
@@ -406,10 +406,10 @@
#define GEN9_WM_CHICKEN3			_MMIO(0x5588)
#define   GEN9_FACTOR_IN_CLR_VAL_HIZ		(1 << 9)

#define CHICKEN_RASTER_1			_MMIO(0x6204)
#define CHICKEN_RASTER_1			MCR_REG(0x6204)
#define   DIS_SF_ROUND_NEAREST_EVEN		REG_BIT(8)

#define CHICKEN_RASTER_2			_MMIO(0x6208)
#define CHICKEN_RASTER_2			MCR_REG(0x6208)
#define   TBIMR_FAST_CLIP			REG_BIT(5)

#define VFLSKPD					MCR_REG(0x62a8)
+28 −6
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ static int ilk_do_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask,
static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
{
	struct intel_uncore *uncore = gt->uncore;
	int loops = 2;
	int err;

	/*
@@ -285,18 +286,39 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
	 * for fifo space for the write or forcewake the chip for
	 * the read
	 */
	do {
		intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);

	/* Wait for the device to ack the reset requests */
	err = __intel_wait_for_register_fw(uncore,
					   GEN6_GDRST, hw_domain_mask, 0,
					   500, 0,
		/*
		 * Wait for the device to ack the reset requests.
		 *
		 * On some platforms, e.g. Jasperlake, we see that the
		 * engine register state is not cleared until shortly after
		 * GDRST reports completion, causing a failure as we try
		 * to immediately resume while the internal state is still
		 * in flux. If we immediately repeat the reset, the second
		 * reset appears to serialise with the first, and since
		 * it is a no-op, the registers should retain their reset
		 * value. However, there is still a concern that upon
		 * leaving the second reset, the internal engine state
		 * is still in flux and not ready for resuming.
		 */
		err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
						   hw_domain_mask, 0,
						   2000, 0,
						   NULL);
	} while (err == 0 && --loops);
	if (err)
		GT_TRACE(gt,
			 "Wait for 0x%08x engines reset failed\n",
			 hw_domain_mask);

	/*
	 * As we have observed that the engine state is still volatile
	 * after GDRST is acked, impose a small delay to let everything settle.
	 */
	udelay(50);

	return err;
}

+2 −2
Original line number Diff line number Diff line
@@ -645,7 +645,7 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,
static void dg2_ctx_gt_tuning_init(struct intel_engine_cs *engine,
				   struct i915_wa_list *wal)
{
	wa_masked_en(wal, CHICKEN_RASTER_2, TBIMR_FAST_CLIP);
	wa_mcr_masked_en(wal, CHICKEN_RASTER_2, TBIMR_FAST_CLIP);
	wa_mcr_write_clr_set(wal, XEHP_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK,
			     REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f));
	wa_mcr_add(wal,
@@ -775,7 +775,7 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine,
		wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);

	/* Wa_15010599737:dg2 */
	wa_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
	wa_mcr_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
}

static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,
+1 −1
Original line number Diff line number Diff line
@@ -2116,7 +2116,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm)
	if (!obj->mm.rsgt)
		return -EBUSY;

	err = dma_resv_reserve_fences(obj->base.resv, 1);
	err = dma_resv_reserve_fences(obj->base.resv, 2);
	if (err)
		return -EBUSY;