diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 3aef127..a61c0d4 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -184,60 +184,61 @@ static struct mode_size {
 	{1440,  900},
 	{1400, 1050},
 	{1680, 1050},
 	{1600, 1200},
 	{1920, 1080},
 	{1920, 1200}
 };
 
 static int qxl_add_common_modes(struct drm_connector *connector,
                                 unsigned pwidth,
                                 unsigned pheight)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_display_mode *mode = NULL;
 	int i;
 	for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
 		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h,
 				    60, false, false, false);
 		if (common_modes[i].w == pwidth && common_modes[i].h == pheight)
 			mode->type |= DRM_MODE_TYPE_PREFERRED;
 		drm_mode_probed_add(connector, mode);
 	}
 	return i - 1;
 }
 
 static void qxl_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
 
 	drm_crtc_cleanup(crtc);
+	qxl_bo_unref(&qxl_crtc->cursor_bo);
 	kfree(qxl_crtc);
 }
 
 static int qxl_crtc_page_flip(struct drm_crtc *crtc,
                               struct drm_framebuffer *fb,
                               struct drm_pending_vblank_event *event,
                               uint32_t page_flip_flags)
 {
 	struct drm_device *dev = crtc->dev;
 	struct qxl_device *qdev = dev->dev_private;
 	struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb);
 	struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb);
 	struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj);
 	struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj);
 	unsigned long flags;
 	struct drm_clip_rect norect = {
 	    .x1 = 0,
 	    .y1 = 0,
 	    .x2 = fb->width,
 	    .y2 = fb->height
 	};
 	int inc = 1;
 	int one_clip_rect = 1;
 	int ret = 0;
 
 	crtc->primary->fb = fb;
 	bo_old->is_primary = false;
 	bo->is_primary = true;
 
 	ret = qxl_bo_reserve(bo, false);
@@ -269,60 +270,106 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
 	return 0;
 }
 
 static int
 qxl_hide_cursor(struct qxl_device *qdev)
 {
 	struct qxl_release *release;
 	struct qxl_cursor_cmd *cmd;
 	int ret;
 
 	ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD,
 					 &release, NULL);
 	if (ret)
 		return ret;
 
 	ret = qxl_release_reserve_list(release, true);
 	if (ret) {
 		qxl_release_free(qdev, release);
 		return ret;
 	}
 
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_HIDE;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	qxl_release_fence_buffer_objects(release);
 	return 0;
 }
 
+static int qxl_crtc_apply_cursor(struct drm_crtc *crtc)
+{
+	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct qxl_device *qdev = dev->dev_private;
+	struct qxl_cursor_cmd *cmd;
+	struct qxl_release *release;
+	int ret = 0;
+
+	if (!qcrtc->cursor_bo)
+		return 0;
+
+	ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd),
+					 QXL_RELEASE_CURSOR_CMD,
+					 &release, NULL);
+	if (ret)
+		return ret;
+
+	ret = qxl_release_list_add(release, qcrtc->cursor_bo);
+	if (ret)
+		goto out_free_release;
+
+	ret = qxl_release_reserve_list(release, false);
+	if (ret)
+		goto out_free_release;
+
+	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
+	cmd->type = QXL_CURSOR_SET;
+	cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
+	cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
+
+	cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0);
+
+	cmd->u.set.visible = 1;
+	qxl_release_unmap(qdev, release, &cmd->release_info);
+
+	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+	qxl_release_fence_buffer_objects(release);
+
+	return ret;
+
+out_free_release:
+	qxl_release_free(qdev, release);
+	return ret;
+}
+
 static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
 				struct drm_file *file_priv,
 				uint32_t handle,
 				uint32_t width,
 				uint32_t height, int32_t hot_x, int32_t hot_y)
 {
 	struct drm_device *dev = crtc->dev;
 	struct qxl_device *qdev = dev->dev_private;
 	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
 	struct drm_gem_object *obj;
 	struct qxl_cursor *cursor;
 	struct qxl_cursor_cmd *cmd;
 	struct qxl_bo *cursor_bo, *user_bo;
 	struct qxl_release *release;
 	void *user_ptr;
 
 	int size = 64*64*4;
 	int ret = 0;
 	if (!handle)
 		return qxl_hide_cursor(qdev);
 
 	obj = drm_gem_object_lookup(file_priv, handle);
 	if (!obj) {
 		DRM_ERROR("cannot find cursor object\n");
 		return -ENOENT;
 	}
 
 	user_bo = gem_to_qxl_bo(obj);
 
 	ret = qxl_bo_reserve(user_bo, false);
@@ -373,61 +420,62 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
 	qxl_bo_kunmap(cursor_bo);
 
 	qxl_bo_kunmap(user_bo);
 
 	qcrtc->cur_x += qcrtc->hot_spot_x - hot_x;
 	qcrtc->cur_y += qcrtc->hot_spot_y - hot_y;
 	qcrtc->hot_spot_x = hot_x;
 	qcrtc->hot_spot_y = hot_y;
 
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_SET;
 	cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
 	cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
 
 	cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0);
 
 	cmd->u.set.visible = 1;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	qxl_release_fence_buffer_objects(release);
 
 	/* finish with the userspace bo */
 	ret = qxl_bo_reserve(user_bo, false);
 	if (!ret) {
 		qxl_bo_unpin(user_bo);
 		qxl_bo_unreserve(user_bo);
 	}
 	drm_gem_object_unreference_unlocked(obj);
 
-	qxl_bo_unref(&cursor_bo);
+	qxl_bo_unref (&qcrtc->cursor_bo);
+	qcrtc->cursor_bo = cursor_bo;
 
 	return ret;
 
 out_backoff:
 	qxl_release_backoff_reserve_list(release);
 out_free_bo:
 	qxl_bo_unref(&cursor_bo);
 out_free_release:
 	qxl_release_free(qdev, release);
 out_kunmap:
 	qxl_bo_kunmap(user_bo);
 out_unpin:
 	qxl_bo_unpin(user_bo);
 out_unref:
 	drm_gem_object_unreference_unlocked(obj);
 	return ret;
 }
 
 static int qxl_crtc_cursor_move(struct drm_crtc *crtc,
 				int x, int y)
 {
 	struct drm_device *dev = crtc->dev;
 	struct qxl_device *qdev = dev->dev_private;
 	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
 	struct qxl_release *release;
 	struct qxl_cursor_cmd *cmd;
 	int ret;
 
 	ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD,
 				   &release, NULL);
@@ -628,60 +676,66 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
 		  x, y,
 		  mode->hdisplay, mode->vdisplay,
 		  adjusted_mode->hdisplay,
 		  adjusted_mode->vdisplay);
 
 	if (bo->is_primary == false)
 		recreate_primary = true;
 
 	if (bo->surf.stride * bo->surf.height > qdev->vram_size) {
 		DRM_ERROR("Mode doesn't fit in vram size (vgamem)");
 		return -EINVAL;
         }
 
 	ret = qxl_bo_reserve(bo, false);
 	if (ret != 0)
 		return ret;
 	ret = qxl_bo_pin(bo, bo->type, NULL);
 	if (ret != 0) {
 		qxl_bo_unreserve(bo);
 		return -EINVAL;
 	}
 	qxl_bo_unreserve(bo);
 	if (recreate_primary) {
 		qxl_io_destroy_primary(qdev);
 		qxl_io_log(qdev,
 			   "recreate primary: %dx%d,%d,%d\n",
 			   bo->surf.width, bo->surf.height,
 			   bo->surf.stride, bo->surf.format);
 		qxl_io_create_primary(qdev, 0, bo);
 		bo->is_primary = true;
+
+		ret = qxl_crtc_apply_cursor(crtc);
+		if (ret) {
+			DRM_ERROR("could not set cursor after modeset");
+			ret = 0;
+		}
 	}
 
 	if (bo->is_primary) {
 		DRM_DEBUG_KMS("setting surface_id to 0 for primary surface %d on crtc %d\n", bo->surface_id, qcrtc->index);
 		surf_id = 0;
 	} else {
 		surf_id = bo->surface_id;
 	}
 
 	if (old_bo && old_bo != bo) {
 		old_bo->is_primary = false;
 		ret = qxl_bo_reserve(old_bo, false);
 		qxl_bo_unpin(old_bo);
 		qxl_bo_unreserve(old_bo);
 	}
 
 	qxl_monitors_config_set(qdev, qcrtc->index, x, y,
 				mode->hdisplay,
 				mode->vdisplay, surf_id);
 	return 0;
 }
 
 static void qxl_crtc_prepare(struct drm_crtc *crtc)
 {
 	DRM_DEBUG("current: %dx%d+%d+%d (%d).\n",
 		  crtc->mode.hdisplay, crtc->mode.vdisplay,
 		  crtc->x, crtc->y, crtc->enabled);
 }
 
 static void qxl_crtc_commit(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 8e633ca..5f3e5ad 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -110,60 +110,61 @@ struct qxl_bo {
 	void				*kptr;
 	int                             type;
 
 	/* Constant after initialization */
 	struct drm_gem_object		gem_base;
 	bool is_primary; /* is this now a primary surface */
 	bool hw_surf_alloc;
 	struct qxl_surface surf;
 	uint32_t surface_id;
 	struct qxl_release *surf_create;
 };
 #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base)
 #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo)
 
 struct qxl_gem {
 	struct mutex		mutex;
 	struct list_head	objects;
 };
 
 struct qxl_bo_list {
 	struct ttm_validate_buffer tv;
 };
 
 struct qxl_crtc {
 	struct drm_crtc base;
 	int index;
 	int cur_x;
 	int cur_y;
 	int hot_spot_x;
 	int hot_spot_y;
+	struct qxl_bo *cursor_bo;
 };
 
 struct qxl_output {
 	int index;
 	struct drm_connector base;
 	struct drm_encoder enc;
 };
 
 struct qxl_framebuffer {
 	struct drm_framebuffer base;
 	struct drm_gem_object *obj;
 };
 
 #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base)
 #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base)
 #define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc)
 #define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base)
 
 struct qxl_mman {
 	struct ttm_bo_global_ref        bo_global_ref;
 	struct drm_global_reference	mem_global_ref;
 	bool				mem_global_referenced;
 	struct ttm_bo_device		bdev;
 };
 
 struct qxl_mode_info {
 	int num_modes;
 	struct qxl_mode *modes;
 	bool mode_config_initialized;
 
