{
        struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
 
+       qxl_bo_unref(&qxl_crtc->cursor_bo);
        drm_crtc_cleanup(crtc);
        kfree(qxl_crtc);
 }
        return 0;
 }
 
+static int qxl_primary_apply_cursor(struct drm_plane *plane)
+{
+       struct drm_device *dev = plane->dev;
+       struct qxl_device *qdev = dev->dev_private;
+       struct drm_framebuffer *fb = plane->state->fb;
+       struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
+       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 = plane->state->crtc_x + fb->hot_x;
+       cmd->u.set.position.y = plane->state->crtc_y + fb->hot_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 void qxl_primary_atomic_update(struct drm_plane *plane,
                                      struct drm_plane_state *old_state)
 {
            .x2 = qfb->base.width,
            .y2 = qfb->base.height
        };
+       int ret;
        bool same_shadow = false;
 
        if (old_state->fb) {
                if (!same_shadow)
                        qxl_io_destroy_primary(qdev);
                bo_old->is_primary = false;
+
+               ret = qxl_primary_apply_cursor(plane);
+               if (ret)
+                       DRM_ERROR(
+                       "could not set cursor after creating primary");
        }
 
        if (!bo->is_primary) {
        struct drm_device *dev = plane->dev;
        struct qxl_device *qdev = dev->dev_private;
        struct drm_framebuffer *fb = plane->state->fb;
+       struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc);
        struct qxl_release *release;
        struct qxl_cursor_cmd *cmd;
        struct qxl_cursor *cursor;
                cmd->u.set.shape = qxl_bo_physical_address(qdev,
                                                           cursor_bo, 0);
                cmd->type = QXL_CURSOR_SET;
+
+               qxl_bo_unref(&qcrtc->cursor_bo);
+               qcrtc->cursor_bo = cursor_bo;
+               cursor_bo = NULL;
        } else {
 
                ret = qxl_release_reserve_list(release, true);