diff options
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_ioctl.c')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_ioctl.c | 46 |
1 files changed, 17 insertions, 29 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index b110883f8253..bda5c5f80c24 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -107,9 +107,9 @@ apply_surf_reloc(struct qxl_device *qdev, struct qxl_reloc_info *info) } /* return holding the reference to this object */ -static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device *qdev, - struct drm_file *file_priv, uint64_t handle, - struct qxl_release *release) +static int qxlhw_handle_to_bo(struct qxl_device *qdev, + struct drm_file *file_priv, uint64_t handle, + struct qxl_release *release, struct qxl_bo **qbo_p) { struct drm_gem_object *gobj; struct qxl_bo *qobj; @@ -117,15 +117,17 @@ static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device *qdev, gobj = drm_gem_object_lookup(qdev->ddev, file_priv, handle); if (!gobj) - return NULL; + return -EINVAL; qobj = gem_to_qxl_bo(gobj); ret = qxl_release_list_add(release, qobj); + drm_gem_object_unreference_unlocked(gobj); if (ret) - return NULL; + return ret; - return qobj; + *qbo_p = qobj; + return 0; } /* @@ -143,7 +145,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, struct qxl_release *release; struct qxl_bo *cmd_bo; void *fb_cmd; - int i, j, ret, num_relocs; + int i, ret, num_relocs; int unwritten; switch (cmd->type) { @@ -210,7 +212,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, /* add the bos to the list of bos to validate - need to validate first then process relocs? */ if (reloc.reloc_type != QXL_RELOC_TYPE_BO && reloc.reloc_type != QXL_RELOC_TYPE_SURF) { - DRM_DEBUG("unknown reloc type %d\n", reloc_info[i].type); + DRM_DEBUG("unknown reloc type %d\n", reloc.reloc_type); ret = -EINVAL; goto out_free_bos; @@ -218,13 +220,10 @@ static int qxl_process_single_command(struct qxl_device *qdev, reloc_info[i].type = reloc.reloc_type; if (reloc.dst_handle) { - reloc_info[i].dst_bo = qxlhw_handle_to_bo(qdev, file_priv, - reloc.dst_handle, release); - if (!reloc_info[i].dst_bo) { - ret = -EINVAL; - reloc_info[i].src_bo = NULL; + ret = qxlhw_handle_to_bo(qdev, file_priv, reloc.dst_handle, release, + &reloc_info[i].dst_bo); + if (ret) goto out_free_bos; - } reloc_info[i].dst_offset = reloc.dst_offset; } else { reloc_info[i].dst_bo = cmd_bo; @@ -233,16 +232,11 @@ static int qxl_process_single_command(struct qxl_device *qdev, num_relocs++; /* reserve and validate the reloc dst bo */ - if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle > 0) { - reloc_info[i].src_bo = - qxlhw_handle_to_bo(qdev, file_priv, - reloc.src_handle, release); - if (!reloc_info[i].src_bo) { - if (reloc_info[i].dst_bo != cmd_bo) - drm_gem_object_unreference_unlocked(&reloc_info[i].dst_bo->gem_base); - ret = -EINVAL; + if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle) { + ret = qxlhw_handle_to_bo(qdev, file_priv, reloc.src_handle, release, + &reloc_info[i].src_bo); + if (ret) goto out_free_bos; - } reloc_info[i].src_offset = reloc.src_offset; } else { reloc_info[i].src_bo = NULL; @@ -269,12 +263,6 @@ static int qxl_process_single_command(struct qxl_device *qdev, qxl_release_fence_buffer_objects(release); out_free_bos: - for (j = 0; j < num_relocs; j++) { - if (reloc_info[j].dst_bo != cmd_bo) - drm_gem_object_unreference_unlocked(&reloc_info[j].dst_bo->gem_base); - if (reloc_info[j].src_bo && reloc_info[j].src_bo != cmd_bo) - drm_gem_object_unreference_unlocked(&reloc_info[j].src_bo->gem_base); - } out_free_release: if (ret) qxl_release_free(qdev, release); |