diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4d58167..7d06a66 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2431,6 +2431,9 @@ int gen8_gem_context_init(struct drm_device *dev);
 int gen8_create_lr_context(struct i915_hw_context *ctx,
 			   struct intel_engine *ring,
 			   struct drm_i915_file_private *file_priv);
+struct i915_hw_context *
+gen8_gem_validate_context(struct drm_device *dev, struct drm_file *file,
+			  struct intel_engine *ring, const u32 ctx_id);
 
 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e4e616d..d4c6863 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -181,6 +181,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
 	struct i915_hw_context *ctx = container_of(ctx_ref,
 						   typeof(*ctx), ref);
 	struct i915_hw_ppgtt *ppgtt = NULL;
+	bool ppgtt_unref = false;
 	int i;
 
 	for (i = 0; i < I915_NUM_RINGS; i++) {
@@ -188,12 +189,12 @@ void i915_gem_context_free(struct kref *ctx_ref)
 		struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf;
 
 		if (ctx_obj) {
-			if (i == RCS) {
-				/* We refcount even the aliasing PPGTT to keep the
-				 * code symmetric */
-				if (USES_PPGTT(ctx_obj->base.dev))
-					ppgtt = ctx_to_ppgtt(ctx);
-			}
+			struct drm_device *dev = ctx_obj->base.dev;
+			struct drm_i915_private *dev_priv = to_i915(dev);
+			ppgtt_unref = USES_PPGTT(dev);
+
+			if (dev_priv->lrc_enabled && ctx->file_priv)
+				i915_gem_object_ggtt_unpin(ctx_obj);
 
 			/* XXX: Free up the object before tearing down the address
 			 * space, in case we're bound in the PPGTT */
@@ -207,8 +208,13 @@ void i915_gem_context_free(struct kref *ctx_ref)
 		}
 	}
 
-	if (ppgtt)
-		kref_put(&ppgtt->ref, ppgtt_release);
+	if (ppgtt_unref) {
+		/* We refcount even the aliasing PPGTT to keep the
+		 * code symmetric */
+		ppgtt = ctx_to_ppgtt(ctx);
+		if (ppgtt)
+			kref_put(&ppgtt->ref, ppgtt_release);
+	}
 	list_del(&ctx->link);
 	kfree(ctx);
 }
@@ -550,12 +556,13 @@ static int context_idr_cleanup(int id, void *p, void *data)
 int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 
 	idr_init(&file_priv->context_idr);
 
 	mutex_lock(&dev->struct_mutex);
-	file_priv->private_default_ctx =
-		i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev), true);
+	file_priv->private_default_ctx = i915_gem_create_context(dev, file_priv,
+			USES_FULL_PPGTT(dev), !dev_priv->lrc_enabled);
 	mutex_unlock(&dev->struct_mutex);
 
 	if (IS_ERR(file_priv->private_default_ctx)) {
@@ -801,6 +808,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 {
 	struct drm_i915_gem_context_create *args = data;
 	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct i915_hw_context *ctx;
 	int ret;
 
@@ -811,7 +819,8 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 	if (ret)
 		return ret;
 
-	ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev), true);
+	ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev),
+			!dev_priv->lrc_enabled);
 	mutex_unlock(&dev->struct_mutex);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 823ad3d..f7dad8c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1190,7 +1190,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		goto pre_mutex_err;
 	}
 
-	ctx = i915_gem_validate_context(dev, file, ring, ctx_id);
+	if (dev_priv->lrc_enabled)
+		ctx = gen8_gem_validate_context(dev, file, ring, ctx_id);
+	else
+		ctx = i915_gem_validate_context(dev, file, ring, ctx_id);
 	if (IS_ERR(ctx)) {
 		mutex_unlock(&dev->struct_mutex);
 		ret = PTR_ERR(ctx);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 5a85496..a656b48 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -78,6 +78,40 @@
 #define CTX_R_PWR_CLK_STATE		0x42
 #define CTX_GPGPU_CSR_BASE_ADDRESS	0x44
 
+struct i915_hw_context *
+gen8_gem_validate_context(struct drm_device *dev, struct drm_file *file,
+			  struct intel_engine *ring, const u32 ctx_id)
+{
+	struct i915_hw_context *ctx = NULL;
+	struct i915_ctx_hang_stats *hs;
+
+	/* There is no reason why we cannot accept non-default, non-render contexts,
+	 * other than it changes the ABI (these kind of custom contexts have not been
+	 * allowed before) */
+	if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_ID)
+		return ERR_PTR(-EINVAL);
+
+	ctx = i915_gem_context_get(file->driver_priv, ctx_id);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	hs = &ctx->hang_stats;
+	if (hs->banned) {
+		DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
+		return ERR_PTR(-EIO);
+	}
+
+	if (!ctx->engine[ring->id].obj) {
+		int ret = gen8_create_lr_context(ctx, ring, file->driver_priv);
+		if (ret) {
+			DRM_DEBUG("Could not create LRC %u\n", ctx_id);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return ctx;
+}
+
 static int
 intel_populate_lr_context(struct i915_hw_context *ctx,
 			  struct intel_engine *ring)
