diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8beec97fa348bb1ad544a2b295dd77379f42bc2d..f4f714e39b7b6e2f15db60dd1065710ebdf75c75 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1470,6 +1470,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
 	int i;
 
 	BUG_ON(obj_priv->pages_refcount == 0);
+	BUG_ON(obj_priv->madv == __I915_MADV_PURGED);
 
 	if (--obj_priv->pages_refcount != 0)
 		return;
@@ -1534,11 +1535,14 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 static void
 i915_gem_object_truncate(struct drm_gem_object *obj)
 {
-    struct inode *inode;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct inode *inode;
 
-    inode = obj->filp->f_path.dentry->d_inode;
-    if (inode->i_op->truncate)
-	    inode->i_op->truncate (inode);
+	inode = obj->filp->f_path.dentry->d_inode;
+	if (inode->i_op->truncate)
+		inode->i_op->truncate (inode);
+
+	obj_priv->madv = __I915_MADV_PURGED;
 }
 
 static inline int
@@ -2559,7 +2563,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 	if (dev_priv->mm.suspended)
 		return -EBUSY;
 
-	if (obj_priv->madv == I915_MADV_DONTNEED) {
+	if (obj_priv->madv != I915_MADV_WILLNEED) {
 		DRM_ERROR("Attempting to bind a purgeable object\n");
 		return -EINVAL;
 	}
@@ -3928,8 +3932,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
 	}
 	obj_priv = obj->driver_private;
 
-	if (obj_priv->madv == I915_MADV_DONTNEED) {
-		DRM_ERROR("Attempting to pin a I915_MADV_DONTNEED buffer\n");
+	if (obj_priv->madv != I915_MADV_WILLNEED) {
+		DRM_ERROR("Attempting to pin a purgeable buffer\n");
 		drm_gem_object_unreference(obj);
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
@@ -4081,14 +4085,16 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
 		return -EINVAL;
 	}
 
-	obj_priv->madv = args->madv;
-	args->retained = obj_priv->gtt_space != NULL;
+	if (obj_priv->madv != __I915_MADV_PURGED)
+		obj_priv->madv = args->madv;
 
 	/* if the object is no longer bound, discard its backing storage */
 	if (i915_gem_object_is_purgeable(obj_priv) &&
 	    obj_priv->gtt_space == NULL)
 		i915_gem_object_truncate(obj);
 
+	args->retained = obj_priv->madv != __I915_MADV_PURGED;
+
 	drm_gem_object_unreference(obj);
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 607c9da061e8d8db0f6222cf6265de306c8eb716..7e0cb1da92e68be66b9f8c0839a42ea0e6a95e99 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -671,6 +671,7 @@ struct drm_i915_get_pipe_from_crtc_id {
 
 #define I915_MADV_WILLNEED 0
 #define I915_MADV_DONTNEED 1
+#define __I915_MADV_PURGED 2 /* internal state */
 
 struct drm_i915_gem_madvise {
 	/** Handle of the buffer to change the backing store advice */