/* We refcount even the aliasing PPGTT to keep the code symmetric */
        if (USES_ALIASING_PPGTT(ctx->obj->base.dev))
-               ppgtt = container_of(ctx->vm, struct i915_hw_ppgtt, base);
+               ppgtt = ctx_to_ppgtt(ctx);
 
        /* XXX: Free up the object before tearing down the address space, in
         * case we're bound in the PPGTT */
 }
 
 static struct i915_hw_context *
-create_hw_context(struct drm_device *dev,
+__create_hw_context(struct drm_device *dev,
                  struct drm_i915_file_private *file_priv)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        if (file_priv == NULL)
                return ctx;
 
-       ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
+       ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0,
                        GFP_KERNEL);
        if (ret < 0)
                goto err_out;
 
 static inline bool is_default_context(struct i915_hw_context *ctx)
 {
-       /* Cheap trick to determine default contexts */
-       return ctx->file_priv ? false : true;
+       return (ctx->id == DEFAULT_CONTEXT_ID);
 }
 
 /**
  * well as an idle case.
  */
 static struct i915_hw_context *
-create_default_context(struct drm_device *dev,
-                      struct drm_i915_file_private *file_priv,
-                      bool create_vm)
+i915_gem_create_context(struct drm_device *dev,
+                       struct drm_i915_file_private *file_priv,
+                       bool create_vm)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_hw_context *ctx;
 
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 
-       /* Not yet supported */
-       BUG_ON(file_priv);
-
-       ctx = create_hw_context(dev, file_priv);
+       ctx = __create_hw_context(dev, file_priv);
        if (IS_ERR(ctx))
                return ctx;
 
                struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(dev, ctx);
 
                if (IS_ERR_OR_NULL(ppgtt)) {
-                       DRM_ERROR("PPGTT setup failed (%ld)\n", PTR_ERR(ppgtt));
+                       DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
+                                        PTR_ERR(ppgtt));
                        ret = PTR_ERR(ppgtt);
                        goto err_destroy;
                } else
        }
 
        dev_priv->ring[RCS].default_context =
-               create_default_context(dev, NULL, USES_ALIASING_PPGTT(dev));
+               i915_gem_create_context(dev, NULL, USES_ALIASING_PPGTT(dev));
 
        if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) {
                DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n",
 {
        struct i915_hw_context *ctx = p;
 
-       BUG_ON(id == DEFAULT_CONTEXT_ID);
+       /* Ignore the default context because close will handle it */
+       if (is_default_context(ctx))
+               return 0;
 
        i915_gem_context_unreference(ctx);
        return 0;
 
        idr_init(&file_priv->context_idr);
 
+       mutex_lock(&dev->struct_mutex);
+       file_priv->private_default_ctx =
+               i915_gem_create_context(dev, file_priv, false);
+       mutex_unlock(&dev->struct_mutex);
+
+       if (IS_ERR(file_priv->private_default_ctx)) {
+               idr_destroy(&file_priv->context_idr);
+               return PTR_ERR(file_priv->private_default_ctx);
+       }
+
        return 0;
 }
 
 
        mutex_lock(&dev->struct_mutex);
        idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
+       i915_gem_context_unreference(file_priv->private_default_ctx);
        idr_destroy(&file_priv->context_idr);
        mutex_unlock(&dev->struct_mutex);
 }
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
        struct i915_hw_context *to;
 
+       WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
        if (!HAS_HW_CONTEXTS(ring->dev))
                return 0;
 
-       WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
-
-       if (to_id == DEFAULT_CONTEXT_ID) {
+       if (file == NULL)
                to = ring->default_context;
-       } else {
-               if (file == NULL)
-                       return -EINVAL;
-
+       else
                to = i915_gem_context_get(file->driver_priv, to_id);
-               if (to == NULL)
-                       return -ENOENT;
-       }
+
+       if (to == NULL)
+               return -ENOENT;
 
        return do_switch(ring, to);
 }
        if (ret)
                return ret;
 
-       ctx = create_hw_context(dev, file_priv);
+       ctx = i915_gem_create_context(dev, file_priv, false);
        mutex_unlock(&dev->struct_mutex);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
        if (!(dev->driver->driver_features & DRIVER_GEM))
                return -ENODEV;
 
+       if (args->ctx_id == DEFAULT_CONTEXT_ID)
+               return -EPERM;
+
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
                return ret;