diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 91b0886..d9470a4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -602,6 +602,9 @@ struct i915_hw_context {
 	struct i915_address_space *vm;
 
 	struct list_head link;
+
+	/* Advanced contexts only */
+	struct list_head dependent_contexts;
 };
 
 struct i915_fbc {
@@ -2321,7 +2324,8 @@ int gen8_gem_context_init(struct drm_device *dev);
 void gen8_gem_context_fini(struct drm_device *dev);
 struct i915_hw_context *gen8_gem_create_context(struct drm_device *dev,
 			struct intel_engine *ring,
-			struct drm_i915_file_private *file_priv, bool create_vm);
+			struct drm_i915_file_private *file_priv,
+			struct i915_hw_context *standalone_ctx, bool create_vm);
 void gen8_gem_context_free(struct i915_hw_context *ctx);
 
 /* i915_gem_evict.c */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6baa5ab..17015b2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -271,6 +271,8 @@ __create_hw_context(struct drm_device *dev,
 	 * is no remap info, it will be a NOP. */
 	ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
 
+	INIT_LIST_HEAD(&ctx->dependent_contexts);
+
 	return ctx;
 
 err_out:
@@ -511,6 +513,12 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 static int context_idr_cleanup(int id, void *p, void *data)
 {
 	struct i915_hw_context *ctx = p;
+	struct i915_hw_context *cursor, *tmp;
+
+	list_for_each_entry_safe(cursor, tmp, &ctx->dependent_contexts, dependent_contexts) {
+		list_del(&cursor->dependent_contexts);
+		i915_gem_context_unreference(cursor);
+	}
 
 	/* Ignore the default context because close will handle it */
 	if (i915_gem_context_is_default(ctx))
@@ -543,7 +551,7 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
 	if (dev_priv->lrc_enabled)
 		file_priv->private_default_ctx = gen8_gem_create_context(dev,
 						&dev_priv->ring[RCS], file_priv,
-						USES_FULL_PPGTT(dev));
+						NULL, USES_FULL_PPGTT(dev));
 	else
 		file_priv->private_default_ctx = i915_gem_create_context(dev,
 						file_priv, USES_FULL_PPGTT(dev));
@@ -805,7 +813,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 
 	if (dev_priv->lrc_enabled)
 		ctx = gen8_gem_create_context(dev, &dev_priv->ring[RCS],
-					file_priv, USES_FULL_PPGTT(dev));
+					file_priv, NULL, USES_FULL_PPGTT(dev));
 	else
 		ctx = i915_gem_create_context(dev, file_priv,
 					USES_FULL_PPGTT(dev));
@@ -825,6 +833,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 	struct drm_i915_gem_context_destroy *args = data;
 	struct drm_i915_file_private *file_priv = file->driver_priv;
 	struct i915_hw_context *ctx;
+	struct i915_hw_context *cursor, *tmp;
 	int ret;
 
 	if (args->ctx_id == DEFAULT_CONTEXT_ID)
@@ -841,6 +850,10 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 	}
 
 	idr_remove(&ctx->file_priv->context_idr, ctx->id);
+	list_for_each_entry_safe(cursor, tmp, &ctx->dependent_contexts, dependent_contexts) {
+		list_del(&cursor->dependent_contexts);
+		i915_gem_context_unreference(cursor);
+	}
 	i915_gem_context_unreference(ctx);
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_lrc.c b/drivers/gpu/drm/i915/i915_lrc.c
index 124e5f2..99011cc 100644
--- a/drivers/gpu/drm/i915/i915_lrc.c
+++ b/drivers/gpu/drm/i915/i915_lrc.c
@@ -195,23 +195,54 @@ intel_populate_lrc(struct i915_hw_context *ctx,
 	return 0;
 }
 
+static void assert_on_ppgtt_release(struct kref *kref)
+{
+	WARN(1, "Are we trying to free the aliasing PPGTT?\n");
+}
+
 struct i915_hw_context *
 gen8_gem_create_context(struct drm_device *dev,
 			struct intel_engine *ring,
 			struct drm_i915_file_private *file_priv,
+			struct i915_hw_context *standalone_ctx,
 			bool create_vm)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct i915_hw_context *ctx = NULL;
 	struct drm_i915_gem_object *ring_obj = NULL;
 	struct intel_ringbuffer *ringbuf = NULL;
+	bool is_dependent;
 	int ret;
 
-	ctx = i915_gem_create_context(dev, file_priv, create_vm);
+	/* NB: a standalone context is the first context with a given id to be
+	 * created for a new fd. Dependent contexts simply hang from the stand-alone,
+	 * sharing their ID and their PPGTT */
+	is_dependent = (file_priv != NULL) && (standalone_ctx != NULL);
+
+	ctx = i915_gem_create_context(dev, is_dependent? NULL : file_priv,
+					is_dependent? false : create_vm);
 	if (IS_ERR_OR_NULL(ctx))
 		return ctx;
 
-	if (file_priv) {
+	if (is_dependent) {
+		struct i915_hw_ppgtt *ppgtt;
+
+		/* We take the same PPGTT as the standalone */
+		ppgtt = ctx_to_ppgtt(ctx);
+		kref_put(&ppgtt->ref, assert_on_ppgtt_release);
+		ppgtt = ctx_to_ppgtt(standalone_ctx);
+		ctx->vm = &ppgtt->base;
+		kref_get(&ppgtt->ref);
+
+		ctx->file_priv = file_priv;
+		ctx->id = standalone_ctx->id;
+		ctx->remap_slice = standalone_ctx->remap_slice;
+
+		list_add_tail(&ctx->dependent_contexts,
+				&standalone_ctx->dependent_contexts);
+	}
+
+	if (file_priv && !is_dependent) {
 		ret = i915_gem_obj_ggtt_pin(ctx->obj, GEN8_CONTEXT_ALIGN, 0);
 		if (ret) {
 			DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
@@ -337,7 +368,7 @@ int gen8_gem_context_init(struct drm_device *dev)
 
 	for_each_ring(ring, dev_priv, ring_id) {
 		ring->default_context = gen8_gem_create_context(dev, ring,
-						NULL, (ring_id == RCS));
+					NULL, NULL, (ring_id == RCS));
 		if (IS_ERR_OR_NULL(ring->default_context)) {
 			ret = PTR_ERR(ring->default_context);
 			DRM_DEBUG_DRIVER("Create ctx failed: %d\n", ret);
