return wa_list_verify(dev_priv, &dev_priv->gt_wa_list, from);
 }
 
-struct whitelist {
-       i915_reg_t reg[RING_MAX_NONPRIV_SLOTS];
-       unsigned int count;
-       u32 nopid;
-};
-
-static void whitelist_reg(struct whitelist *w, i915_reg_t reg)
+static void
+whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)
 {
-       if (GEM_DEBUG_WARN_ON(w->count >= RING_MAX_NONPRIV_SLOTS))
-               return;
-
-       w->reg[w->count++] = reg;
-}
+       struct i915_wa wa = {
+               .reg = reg
+       };
 
-static void bdw_whitelist_build(struct whitelist *w)
-{
-}
+       if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS))
+               return;
 
-static void chv_whitelist_build(struct whitelist *w)
-{
+       wal_add(wal, &wa);
 }
 
-static void gen9_whitelist_build(struct whitelist *w)
+static void gen9_whitelist_build(struct i915_wa_list *w)
 {
        /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
        whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
        whitelist_reg(w, GEN8_HDC_CHICKEN1);
 }
 
-static void skl_whitelist_build(struct whitelist *w)
+static void skl_whitelist_build(struct i915_wa_list *w)
 {
        gen9_whitelist_build(w);
 
        whitelist_reg(w, GEN8_L3SQCREG4);
 }
 
-static void bxt_whitelist_build(struct whitelist *w)
+static void bxt_whitelist_build(struct i915_wa_list *w)
 {
        gen9_whitelist_build(w);
 }
 
-static void kbl_whitelist_build(struct whitelist *w)
+static void kbl_whitelist_build(struct i915_wa_list *w)
 {
        gen9_whitelist_build(w);
 
        whitelist_reg(w, GEN8_L3SQCREG4);
 }
 
-static void glk_whitelist_build(struct whitelist *w)
+static void glk_whitelist_build(struct i915_wa_list *w)
 {
        gen9_whitelist_build(w);
 
        whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
 }
 
-static void cfl_whitelist_build(struct whitelist *w)
+static void cfl_whitelist_build(struct i915_wa_list *w)
 {
        gen9_whitelist_build(w);
 }
 
-static void cnl_whitelist_build(struct whitelist *w)
+static void cnl_whitelist_build(struct i915_wa_list *w)
 {
        /* WaEnablePreemptionGranularityControlByUMD:cnl */
        whitelist_reg(w, GEN8_CS_CHICKEN1);
 }
 
-static void icl_whitelist_build(struct whitelist *w)
+static void icl_whitelist_build(struct i915_wa_list *w)
 {
        /* WaAllowUMDToModifyHalfSliceChicken7:icl */
        whitelist_reg(w, GEN9_HALF_SLICE_CHICKEN7);
        whitelist_reg(w, GEN10_SAMPLER_MODE);
 }
 
-static struct whitelist *whitelist_build(struct intel_engine_cs *engine,
-                                        struct whitelist *w)
+void intel_engine_init_whitelist(struct intel_engine_cs *engine)
 {
        struct drm_i915_private *i915 = engine->i915;
+       struct i915_wa_list *w = &engine->whitelist;
 
        GEM_BUG_ON(engine->id != RCS);
 
-       w->count = 0;
-       w->nopid = i915_mmio_reg_offset(RING_NOPID(engine->mmio_base));
+       wa_init_start(w, "whitelist");
 
        if (INTEL_GEN(i915) < 8)
-               return NULL;
+               return;
        else if (IS_BROADWELL(i915))
-               bdw_whitelist_build(w);
+               return;
        else if (IS_CHERRYVIEW(i915))
-               chv_whitelist_build(w);
+               return;
        else if (IS_SKYLAKE(i915))
                skl_whitelist_build(w);
        else if (IS_BROXTON(i915))
        else
                MISSING_CASE(INTEL_GEN(i915));
 
-       return w;
+       wa_init_finish(w);
 }
 
-static void whitelist_apply(struct intel_engine_cs *engine,
-                           const struct whitelist *w)
+void intel_engine_apply_whitelist(struct intel_engine_cs *engine)
 {
        struct drm_i915_private *dev_priv = engine->i915;
+       const struct i915_wa_list *wal = &engine->whitelist;
        const u32 base = engine->mmio_base;
+       struct i915_wa *wa;
        unsigned int i;
 
-       if (!w)
+       if (!wal->count)
                return;
 
-       intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL);
-
-       for (i = 0; i < w->count; i++)
-               I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i),
-                             i915_mmio_reg_offset(w->reg[i]));
+       for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
+               I915_WRITE(RING_FORCE_TO_NONPRIV(base, i),
+                          i915_mmio_reg_offset(wa->reg));
 
        /* And clear the rest just in case of garbage */
        for (; i < RING_MAX_NONPRIV_SLOTS; i++)
-               I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i), w->nopid);
-
-       intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL);
-}
+               I915_WRITE(RING_FORCE_TO_NONPRIV(base, i),
+                          i915_mmio_reg_offset(RING_NOPID(base)));
 
-void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine)
-{
-       struct whitelist w;
-
-       whitelist_apply(engine, whitelist_build(engine, &w));
+       DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
 }
 
 static void rcs_engine_wa_init(struct intel_engine_cs *engine)
 
        return ERR_PTR(err);
 }
 
-static u32 get_whitelist_reg(const struct whitelist *w, unsigned int i)
+static u32
+get_whitelist_reg(const struct intel_engine_cs *engine, unsigned int i)
 {
-       return i < w->count ? i915_mmio_reg_offset(w->reg[i]) : w->nopid;
+       i915_reg_t reg = i < engine->whitelist.count ?
+                        engine->whitelist.list[i].reg :
+                        RING_NOPID(engine->mmio_base);
+
+       return i915_mmio_reg_offset(reg);
 }
 
-static void print_results(const struct whitelist *w, const u32 *results)
+static void
+print_results(const struct intel_engine_cs *engine, const u32 *results)
 {
        unsigned int i;
 
        for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
-               u32 expected = get_whitelist_reg(w, i);
+               u32 expected = get_whitelist_reg(engine, i);
                u32 actual = results[i];
 
                pr_info("RING_NONPRIV[%d]: expected 0x%08x, found 0x%08x\n",
        }
 }
 
-static int check_whitelist(const struct whitelist *w,
-                          struct i915_gem_context *ctx,
+static int check_whitelist(struct i915_gem_context *ctx,
                           struct intel_engine_cs *engine)
 {
        struct drm_i915_gem_object *results;
        }
 
        for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
-               u32 expected = get_whitelist_reg(w, i);
+               u32 expected = get_whitelist_reg(engine, i);
                u32 actual = vaddr[i];
 
                if (expected != actual) {
-                       print_results(w, vaddr);
+                       print_results(engine, vaddr);
                        pr_err("Invalid RING_NONPRIV[%d], expected 0x%08x, found 0x%08x\n",
                               i, expected, actual);
 
 
 static int check_whitelist_across_reset(struct intel_engine_cs *engine,
                                        int (*reset)(struct intel_engine_cs *),
-                                       const struct whitelist *w,
                                        const char *name)
 {
        struct drm_i915_private *i915 = engine->i915;
        int err;
 
        pr_info("Checking %d whitelisted registers (RING_NONPRIV) [%s]\n",
-               w->count, name);
+               engine->whitelist.count, name);
 
        if (want_spin) {
                err = igt_spinner_init(&spin, i915);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       err = check_whitelist(w, ctx, engine);
+       err = check_whitelist(ctx, engine);
        if (err) {
                pr_err("Invalid whitelist *before* %s reset!\n", name);
                goto out;
                goto out;
        }
 
-       err = check_whitelist(w, ctx, engine);
+       err = check_whitelist(ctx, engine);
        if (err) {
                pr_err("Whitelist not preserved in context across %s reset!\n",
                       name);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       err = check_whitelist(w, ctx, engine);
+       err = check_whitelist(ctx, engine);
        if (err) {
                pr_err("Invalid whitelist *after* %s reset in fresh context!\n",
                       name);
 {
        struct drm_i915_private *i915 = arg;
        struct intel_engine_cs *engine = i915->engine[RCS];
-       struct whitelist w;
        int err = 0;
 
        /* If we reset the gpu, we should not lose the RING_NONPRIV */
 
-       if (!engine)
-               return 0;
-
-       if (!whitelist_build(engine, &w))
+       if (!engine || engine->whitelist.count == 0)
                return 0;
 
        igt_global_reset_lock(i915);
 
        if (intel_has_reset_engine(i915)) {
                err = check_whitelist_across_reset(engine,
-                                                  do_engine_reset, &w,
+                                                  do_engine_reset,
                                                   "engine");
                if (err)
                        goto out;
 
        if (intel_has_gpu_reset(i915)) {
                err = check_whitelist_across_reset(engine,
-                                                  do_device_reset, &w,
+                                                  do_device_reset,
                                                   "device");
                if (err)
                        goto out;