Commit 51883883 authored by Dave Airlie's avatar Dave Airlie

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
...@@ -1688,6 +1688,10 @@ void i915_gem_init__contexts(struct drm_i915_private *i915) ...@@ -1688,6 +1688,10 @@ void i915_gem_init__contexts(struct drm_i915_private *i915)
init_contexts(&i915->gem.contexts); 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, static void gem_context_register(struct i915_gem_context *ctx,
struct drm_i915_file_private *fpriv, struct drm_i915_file_private *fpriv,
u32 id) u32 id)
...@@ -1703,10 +1707,6 @@ static void gem_context_register(struct i915_gem_context *ctx, ...@@ -1703,10 +1707,6 @@ static void gem_context_register(struct i915_gem_context *ctx,
snprintf(ctx->name, sizeof(ctx->name), "%s[%d]", snprintf(ctx->name, sizeof(ctx->name), "%s[%d]",
current->comm, pid_nr(ctx->pid)); 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); spin_lock(&ctx->client->ctx_lock);
list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list); list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list);
spin_unlock(&ctx->client->ctx_lock); spin_unlock(&ctx->client->ctx_lock);
...@@ -1714,6 +1714,10 @@ static void gem_context_register(struct i915_gem_context *ctx, ...@@ -1714,6 +1714,10 @@ static void gem_context_register(struct i915_gem_context *ctx,
spin_lock(&i915->gem.contexts.lock); spin_lock(&i915->gem.contexts.lock);
list_add_tail(&ctx->link, &i915->gem.contexts.list); list_add_tail(&ctx->link, &i915->gem.contexts.list);
spin_unlock(&i915->gem.contexts.lock); 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, 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, ...@@ -2199,14 +2203,22 @@ finalize_create_context_locked(struct drm_i915_file_private *file_priv,
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return 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); gem_context_register(ctx, file_priv, id);
old = xa_erase(&file_priv->proto_context_xa, id); old = xa_erase(&file_priv->proto_context_xa, id);
GEM_BUG_ON(old != pc); GEM_BUG_ON(old != pc);
proto_context_close(file_priv->dev_priv, pc); proto_context_close(file_priv->dev_priv, pc);
/* One for the xarray and one for the caller */ return ctx;
return i915_gem_context_get(ctx);
} }
struct i915_gem_context * struct i915_gem_context *
......
...@@ -406,10 +406,10 @@ ...@@ -406,10 +406,10 @@
#define GEN9_WM_CHICKEN3 _MMIO(0x5588) #define GEN9_WM_CHICKEN3 _MMIO(0x5588)
#define GEN9_FACTOR_IN_CLR_VAL_HIZ (1 << 9) #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 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 TBIMR_FAST_CLIP REG_BIT(5)
#define VFLSKPD MCR_REG(0x62a8) #define VFLSKPD MCR_REG(0x62a8)
......
...@@ -278,6 +278,7 @@ static int ilk_do_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask, ...@@ -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) static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
{ {
struct intel_uncore *uncore = gt->uncore; struct intel_uncore *uncore = gt->uncore;
int loops = 2;
int err; int err;
/* /*
...@@ -285,18 +286,39 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) ...@@ -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 * for fifo space for the write or forcewake the chip for
* the read * the read
*/ */
intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask); 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, * Wait for the device to ack the reset requests.
GEN6_GDRST, hw_domain_mask, 0, *
500, 0, * On some platforms, e.g. Jasperlake, we see that the
NULL); * 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) if (err)
GT_TRACE(gt, GT_TRACE(gt,
"Wait for 0x%08x engines reset failed\n", "Wait for 0x%08x engines reset failed\n",
hw_domain_mask); 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; return err;
} }
......
...@@ -645,7 +645,7 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, ...@@ -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, static void dg2_ctx_gt_tuning_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal) 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, wa_mcr_write_clr_set(wal, XEHP_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK,
REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f)); REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f));
wa_mcr_add(wal, wa_mcr_add(wal,
...@@ -775,7 +775,7 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine, ...@@ -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_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);
/* Wa_15010599737:dg2 */ /* 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, static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,
......
...@@ -2116,7 +2116,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm) ...@@ -2116,7 +2116,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm)
if (!obj->mm.rsgt) if (!obj->mm.rsgt)
return -EBUSY; return -EBUSY;
err = dma_resv_reserve_fences(obj->base.resv, 1); err = dma_resv_reserve_fences(obj->base.resv, 2);
if (err) if (err)
return -EBUSY; return -EBUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment