Commit 96ebf7cb authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-vmwgfx-fixes' of ssh://people.freedesktop.org/~syeh/repos_linux into drm-fixes

vmwgfx cleanups and fixes.

* 'drm-vmwgfx-fixes' of ssh://people.freedesktop.org/~syeh/repos_linux:
  drm/vmwgfx: Adjust checks for null pointers in 13 functions
  drm/vmwgfx: Use memdup_user() rather than duplicating its implementation
  drm/vmwgfx: Use kmalloc_array() in vmw_surface_define_ioctl()
  drm/vmwgfx: Avoid validating views on view destruction
  drm/vmwgfx: Limit the user-space command buffer size
  drm/vmwgfx: Remove a leftover debug printout
  drm/vmwgfx: Allow resource relocations on byte boundaries
  drm/vmwgfx: Enable SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command
  drm/vmwgfx: Remove call to reservation_object_test_signaled_rcu before wait
  drm/vmwgfx: Replace numeric parameter like 0444 with macro
parents e947f03d 862f6157
...@@ -241,15 +241,15 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, ...@@ -241,15 +241,15 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
void *ptr); void *ptr);
MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
module_param_named(enable_fbdev, enable_fbdev, int, 0600); module_param_named(enable_fbdev, enable_fbdev, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages"); MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages");
module_param_named(force_dma_api, vmw_force_iommu, int, 0600); module_param_named(force_dma_api, vmw_force_iommu, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages"); MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600); module_param_named(restrict_iommu, vmw_restrict_iommu, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages"); MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
module_param_named(force_coherent, vmw_force_coherent, int, 0600); module_param_named(force_coherent, vmw_force_coherent, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU"); MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600); module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes"); MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600); module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#define VMWGFX_DRIVER_DATE "20160210" #define VMWGFX_DRIVER_DATE "20160210"
#define VMWGFX_DRIVER_MAJOR 2 #define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 10 #define VMWGFX_DRIVER_MINOR 11
#define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
......
...@@ -34,18 +34,38 @@ ...@@ -34,18 +34,38 @@
#define VMW_RES_HT_ORDER 12 #define VMW_RES_HT_ORDER 12
/**
* enum vmw_resource_relocation_type - Relocation type for resources
*
* @vmw_res_rel_normal: Traditional relocation. The resource id in the
* command stream is replaced with the actual id after validation.
* @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced
* with a NOP.
* @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id
* after validation is -1, the command is replaced with a NOP. Otherwise no
* action.
*/
enum vmw_resource_relocation_type {
vmw_res_rel_normal,
vmw_res_rel_nop,
vmw_res_rel_cond_nop,
vmw_res_rel_max
};
/** /**
* struct vmw_resource_relocation - Relocation info for resources * struct vmw_resource_relocation - Relocation info for resources
* *
* @head: List head for the software context's relocation list. * @head: List head for the software context's relocation list.
* @res: Non-ref-counted pointer to the resource. * @res: Non-ref-counted pointer to the resource.
* @offset: Offset of 4 byte entries into the command buffer where the * @offset: Offset of single byte entries into the command buffer where the
* id that needs fixup is located. * id that needs fixup is located.
* @rel_type: Type of relocation.
*/ */
struct vmw_resource_relocation { struct vmw_resource_relocation {
struct list_head head; struct list_head head;
const struct vmw_resource *res; const struct vmw_resource *res;
unsigned long offset; u32 offset:29;
enum vmw_resource_relocation_type rel_type:3;
}; };
/** /**
...@@ -109,7 +129,18 @@ static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context, ...@@ -109,7 +129,18 @@ static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
struct vmw_dma_buffer *vbo, struct vmw_dma_buffer *vbo,
bool validate_as_mob, bool validate_as_mob,
uint32_t *p_val_node); uint32_t *p_val_node);
/**
* vmw_ptr_diff - Compute the offset from a to b in bytes
*
* @a: A starting pointer.
* @b: A pointer offset in the same address space.
*
* Returns: The offset in bytes between the two pointers.
*/
static size_t vmw_ptr_diff(void *a, void *b)
{
return (unsigned long) b - (unsigned long) a;
}
/** /**
* vmw_resources_unreserve - unreserve resources previously reserved for * vmw_resources_unreserve - unreserve resources previously reserved for
...@@ -409,11 +440,14 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, ...@@ -409,11 +440,14 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
* @list: Pointer to head of relocation list. * @list: Pointer to head of relocation list.
* @res: The resource. * @res: The resource.
* @offset: Offset into the command buffer currently being parsed where the * @offset: Offset into the command buffer currently being parsed where the
* id that needs fixup is located. Granularity is 4 bytes. * id that needs fixup is located. Granularity is one byte.
* @rel_type: Relocation type.
*/ */
static int vmw_resource_relocation_add(struct list_head *list, static int vmw_resource_relocation_add(struct list_head *list,
const struct vmw_resource *res, const struct vmw_resource *res,
unsigned long offset) unsigned long offset,
enum vmw_resource_relocation_type
rel_type)
{ {
struct vmw_resource_relocation *rel; struct vmw_resource_relocation *rel;
...@@ -425,6 +459,7 @@ static int vmw_resource_relocation_add(struct list_head *list, ...@@ -425,6 +459,7 @@ static int vmw_resource_relocation_add(struct list_head *list,
rel->res = res; rel->res = res;
rel->offset = offset; rel->offset = offset;
rel->rel_type = rel_type;
list_add_tail(&rel->head, list); list_add_tail(&rel->head, list);
return 0; return 0;
...@@ -459,11 +494,24 @@ static void vmw_resource_relocations_apply(uint32_t *cb, ...@@ -459,11 +494,24 @@ static void vmw_resource_relocations_apply(uint32_t *cb,
{ {
struct vmw_resource_relocation *rel; struct vmw_resource_relocation *rel;
/* Validate the struct vmw_resource_relocation member size */
BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29));
BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3));
list_for_each_entry(rel, list, head) { list_for_each_entry(rel, list, head) {
if (likely(rel->res != NULL)) u32 *addr = (u32 *)((unsigned long) cb + rel->offset);
cb[rel->offset] = rel->res->id; switch (rel->rel_type) {
else case vmw_res_rel_normal:
cb[rel->offset] = SVGA_3D_CMD_NOP; *addr = rel->res->id;
break;
case vmw_res_rel_nop:
*addr = SVGA_3D_CMD_NOP;
break;
default:
if (rel->res->id == -1)
*addr = SVGA_3D_CMD_NOP;
break;
}
} }
} }
...@@ -655,7 +703,9 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, ...@@ -655,7 +703,9 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
*p_val = NULL; *p_val = NULL;
ret = vmw_resource_relocation_add(&sw_context->res_relocations, ret = vmw_resource_relocation_add(&sw_context->res_relocations,
res, res,
id_loc - sw_context->buf_start); vmw_ptr_diff(sw_context->buf_start,
id_loc),
vmw_res_rel_normal);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
return ret; return ret;
...@@ -721,7 +771,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, ...@@ -721,7 +771,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv,
return vmw_resource_relocation_add return vmw_resource_relocation_add
(&sw_context->res_relocations, res, (&sw_context->res_relocations, res,
id_loc - sw_context->buf_start); vmw_ptr_diff(sw_context->buf_start, id_loc),
vmw_res_rel_normal);
} }
ret = vmw_user_resource_lookup_handle(dev_priv, ret = vmw_user_resource_lookup_handle(dev_priv,
...@@ -2143,10 +2194,10 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, ...@@ -2143,10 +2194,10 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
return ret; return ret;
return vmw_resource_relocation_add(&sw_context->res_relocations, return vmw_resource_relocation_add(&sw_context->res_relocations,
NULL, &cmd->header.id - NULL,
sw_context->buf_start); vmw_ptr_diff(sw_context->buf_start,
&cmd->header.id),
return 0; vmw_res_rel_nop);
} }
/** /**
...@@ -2188,10 +2239,10 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, ...@@ -2188,10 +2239,10 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv,
return ret; return ret;
return vmw_resource_relocation_add(&sw_context->res_relocations, return vmw_resource_relocation_add(&sw_context->res_relocations,
NULL, &cmd->header.id - NULL,
sw_context->buf_start); vmw_ptr_diff(sw_context->buf_start,
&cmd->header.id),
return 0; vmw_res_rel_nop);
} }
/** /**
...@@ -2848,8 +2899,7 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv, ...@@ -2848,8 +2899,7 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv,
* @header: Pointer to the command header in the command stream. * @header: Pointer to the command header in the command stream.
* *
* Check that the view exists, and if it was not created using this * Check that the view exists, and if it was not created using this
* command batch, make sure it's validated (present in the device) so that * command batch, conditionally make this command a NOP.
* the remove command will not confuse the device.
*/ */
static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context, struct vmw_sw_context *sw_context,
...@@ -2877,10 +2927,16 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, ...@@ -2877,10 +2927,16 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
return ret; return ret;
/* /*
* Add view to the validate list iff it was not created using this * If the view wasn't created during this command batch, it might
* command batch. * have been removed due to a context swapout, so add a
* relocation to conditionally make this command a NOP to avoid
* device errors.
*/ */
return vmw_view_res_val_add(sw_context, view); return vmw_resource_relocation_add(&sw_context->res_relocations,
view,
vmw_ptr_diff(sw_context->buf_start,
&cmd->header.id),
vmw_res_rel_cond_nop);
} }
/** /**
...@@ -3029,6 +3085,35 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, ...@@ -3029,6 +3085,35 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
cmd->body.shaderResourceViewId); cmd->body.shaderResourceViewId);
} }
/**
* vmw_cmd_dx_transfer_from_buffer -
* Validate an SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command
*
* @dev_priv: Pointer to a device private struct.
* @sw_context: The software context being used for this batch.
* @header: Pointer to the command header in the command stream.
*/
static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
SVGA3dCmdHeader *header)
{
struct {
SVGA3dCmdHeader header;
SVGA3dCmdDXTransferFromBuffer body;
} *cmd = container_of(header, typeof(*cmd), header);
int ret;
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
user_surface_converter,
&cmd->body.srcSid, NULL);
if (ret != 0)
return ret;
return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
user_surface_converter,
&cmd->body.destSid, NULL);
}
static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context, struct vmw_sw_context *sw_context,
void *buf, uint32_t *size) void *buf, uint32_t *size)
...@@ -3379,6 +3464,9 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { ...@@ -3379,6 +3464,9 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
&vmw_cmd_buffer_copy_check, true, false, true), &vmw_cmd_buffer_copy_check, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_PRED_COPY_REGION, VMW_CMD_DEF(SVGA_3D_CMD_DX_PRED_COPY_REGION,
&vmw_cmd_pred_copy_check, true, false, true), &vmw_cmd_pred_copy_check, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER,
&vmw_cmd_dx_transfer_from_buffer,
true, false, true),
}; };
static int vmw_cmd_check(struct vmw_private *dev_priv, static int vmw_cmd_check(struct vmw_private *dev_priv,
...@@ -3848,14 +3936,14 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, ...@@ -3848,14 +3936,14 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv,
int ret; int ret;
*header = NULL; *header = NULL;
if (!dev_priv->cman || kernel_commands)
return kernel_commands;
if (command_size > SVGA_CB_MAX_SIZE) { if (command_size > SVGA_CB_MAX_SIZE) {
DRM_ERROR("Command buffer is too large.\n"); DRM_ERROR("Command buffer is too large.\n");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (!dev_priv->cman || kernel_commands)
return kernel_commands;
/* If possible, add a little space for fencing. */ /* If possible, add a little space for fencing. */
cmdbuf_size = command_size + 512; cmdbuf_size = command_size + 512;
cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE); cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE);
...@@ -4232,9 +4320,6 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, ...@@ -4232,9 +4320,6 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
ttm_bo_unref(&query_val.bo); ttm_bo_unref(&query_val.bo);
ttm_bo_unref(&pinned_val.bo); ttm_bo_unref(&pinned_val.bo);
vmw_dmabuf_unreference(&dev_priv->pinned_bo); vmw_dmabuf_unreference(&dev_priv->pinned_bo);
DRM_INFO("Dummy query bo pin count: %d\n",
dev_priv->dummy_query_bo->pin_count);
out_unlock: out_unlock:
return; return;
......
...@@ -574,10 +574,8 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, ...@@ -574,10 +574,8 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
bool nonblock = !!(flags & drm_vmw_synccpu_dontblock); bool nonblock = !!(flags & drm_vmw_synccpu_dontblock);
long lret; long lret;
if (nonblock) lret = reservation_object_wait_timeout_rcu(bo->resv, true, true,
return reservation_object_test_signaled_rcu(bo->resv, true) ? 0 : -EBUSY; nonblock ? 0 : MAX_SCHEDULE_TIMEOUT);
lret = reservation_object_wait_timeout_rcu(bo->resv, true, true, MAX_SCHEDULE_TIMEOUT);
if (!lret) if (!lret)
return -EBUSY; return -EBUSY;
else if (lret < 0) else if (lret < 0)
......
...@@ -324,7 +324,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) ...@@ -324,7 +324,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
if (res->id != -1) { if (res->id != -1) {
cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size()); cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size());
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"destruction.\n"); "destruction.\n");
return; return;
...@@ -397,7 +397,7 @@ static int vmw_legacy_srf_create(struct vmw_resource *res) ...@@ -397,7 +397,7 @@ static int vmw_legacy_srf_create(struct vmw_resource *res)
submit_size = vmw_surface_define_size(srf); submit_size = vmw_surface_define_size(srf);
cmd = vmw_fifo_reserve(dev_priv, submit_size); cmd = vmw_fifo_reserve(dev_priv, submit_size);
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"creation.\n"); "creation.\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -446,11 +446,10 @@ static int vmw_legacy_srf_dma(struct vmw_resource *res, ...@@ -446,11 +446,10 @@ static int vmw_legacy_srf_dma(struct vmw_resource *res,
uint8_t *cmd; uint8_t *cmd;
struct vmw_private *dev_priv = res->dev_priv; struct vmw_private *dev_priv = res->dev_priv;
BUG_ON(val_buf->bo == NULL); BUG_ON(!val_buf->bo);
submit_size = vmw_surface_dma_size(srf); submit_size = vmw_surface_dma_size(srf);
cmd = vmw_fifo_reserve(dev_priv, submit_size); cmd = vmw_fifo_reserve(dev_priv, submit_size);
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"DMA.\n"); "DMA.\n");
return -ENOMEM; return -ENOMEM;
...@@ -538,7 +537,7 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res) ...@@ -538,7 +537,7 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res)
submit_size = vmw_surface_destroy_size(); submit_size = vmw_surface_destroy_size();
cmd = vmw_fifo_reserve(dev_priv, submit_size); cmd = vmw_fifo_reserve(dev_priv, submit_size);
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"eviction.\n"); "eviction.\n");
return -ENOMEM; return -ENOMEM;
...@@ -578,7 +577,7 @@ static int vmw_surface_init(struct vmw_private *dev_priv, ...@@ -578,7 +577,7 @@ static int vmw_surface_init(struct vmw_private *dev_priv,
int ret; int ret;
struct vmw_resource *res = &srf->res; struct vmw_resource *res = &srf->res;
BUG_ON(res_free == NULL); BUG_ON(!res_free);
if (!dev_priv->has_mob) if (!dev_priv->has_mob)
vmw_fifo_resource_inc(dev_priv); vmw_fifo_resource_inc(dev_priv);
ret = vmw_resource_init(dev_priv, res, true, res_free, ret = vmw_resource_init(dev_priv, res, true, res_free,
...@@ -700,7 +699,6 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ...@@ -700,7 +699,6 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
struct drm_vmw_surface_create_req *req = &arg->req; struct drm_vmw_surface_create_req *req = &arg->req;
struct drm_vmw_surface_arg *rep = &arg->rep; struct drm_vmw_surface_arg *rep = &arg->rep;
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
struct drm_vmw_size __user *user_sizes;
int ret; int ret;
int i, j; int i, j;
uint32_t cur_bo_offset; uint32_t cur_bo_offset;
...@@ -748,7 +746,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ...@@ -748,7 +746,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
} }
user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
if (unlikely(user_srf == NULL)) { if (unlikely(!user_srf)) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_no_user_srf; goto out_no_user_srf;
} }
...@@ -763,29 +761,21 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ...@@ -763,29 +761,21 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels));
srf->num_sizes = num_sizes; srf->num_sizes = num_sizes;
user_srf->size = size; user_srf->size = size;
srf->sizes = memdup_user((struct drm_vmw_size __user *)(unsigned long)
srf->sizes = kmalloc(srf->num_sizes * sizeof(*srf->sizes), GFP_KERNEL); req->size_addr,
if (unlikely(srf->sizes == NULL)) { sizeof(*srf->sizes) * srf->num_sizes);
ret = -ENOMEM; if (IS_ERR(srf->sizes)) {
ret = PTR_ERR(srf->sizes);
goto out_no_sizes; goto out_no_sizes;
} }
srf->offsets = kmalloc(srf->num_sizes * sizeof(*srf->offsets), srf->offsets = kmalloc_array(srf->num_sizes,
sizeof(*srf->offsets),
GFP_KERNEL); GFP_KERNEL);
if (unlikely(srf->offsets == NULL)) { if (unlikely(!srf->offsets)) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_no_offsets; goto out_no_offsets;
} }
user_sizes = (struct drm_vmw_size __user *)(unsigned long)
req->size_addr;
ret = copy_from_user(srf->sizes, user_sizes,
srf->num_sizes * sizeof(*srf->sizes));
if (unlikely(ret != 0)) {
ret = -EFAULT;
goto out_no_copy;
}
srf->base_size = *srf->sizes; srf->base_size = *srf->sizes;
srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; srf->autogen_filter = SVGA3D_TEX_FILTER_NONE;
srf->multisample_count = 0; srf->multisample_count = 0;
...@@ -923,7 +913,7 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, ...@@ -923,7 +913,7 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
ret = -EINVAL; ret = -EINVAL;
base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle); base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle);
if (unlikely(base == NULL)) { if (unlikely(!base)) {
DRM_ERROR("Could not find surface to reference.\n"); DRM_ERROR("Could not find surface to reference.\n");
goto out_no_lookup; goto out_no_lookup;
} }
...@@ -1069,7 +1059,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) ...@@ -1069,7 +1059,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res)
cmd = vmw_fifo_reserve(dev_priv, submit_len); cmd = vmw_fifo_reserve(dev_priv, submit_len);
cmd2 = (typeof(cmd2))cmd; cmd2 = (typeof(cmd2))cmd;
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"creation.\n"); "creation.\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1135,7 +1125,7 @@ static int vmw_gb_surface_bind(struct vmw_resource *res, ...@@ -1135,7 +1125,7 @@ static int vmw_gb_surface_bind(struct vmw_resource *res,
submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0); submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0);
cmd1 = vmw_fifo_reserve(dev_priv, submit_size); cmd1 = vmw_fifo_reserve(dev_priv, submit_size);
if (unlikely(cmd1 == NULL)) { if (unlikely(!cmd1)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"binding.\n"); "binding.\n");
return -ENOMEM; return -ENOMEM;
...@@ -1185,7 +1175,7 @@ static int vmw_gb_surface_unbind(struct vmw_resource *res, ...@@ -1185,7 +1175,7 @@ static int vmw_gb_surface_unbind(struct vmw_resource *res,
submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2)); submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2));
cmd = vmw_fifo_reserve(dev_priv, submit_size); cmd = vmw_fifo_reserve(dev_priv, submit_size);
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"unbinding.\n"); "unbinding.\n");
return -ENOMEM; return -ENOMEM;
...@@ -1244,7 +1234,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) ...@@ -1244,7 +1234,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res)
vmw_binding_res_list_scrub(&res->binding_head); vmw_binding_res_list_scrub(&res->binding_head);
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
if (unlikely(cmd == NULL)) { if (unlikely(!cmd)) {
DRM_ERROR("Failed reserving FIFO space for surface " DRM_ERROR("Failed reserving FIFO space for surface "
"destruction.\n"); "destruction.\n");
mutex_unlock(&dev_priv->binding_mutex); mutex_unlock(&dev_priv->binding_mutex);
...@@ -1410,7 +1400,7 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, ...@@ -1410,7 +1400,7 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
user_srf = container_of(base, struct vmw_user_surface, prime.base); user_srf = container_of(base, struct vmw_user_surface, prime.base);
srf = &user_srf->srf; srf = &user_srf->srf;
if (srf->res.backup == NULL) { if (!srf->res.backup) {
DRM_ERROR("Shared GB surface is missing a backup buffer.\n"); DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
goto out_bad_resource; goto out_bad_resource;
} }
...@@ -1524,7 +1514,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, ...@@ -1524,7 +1514,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
} }
user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
if (unlikely(user_srf == NULL)) { if (unlikely(!user_srf)) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_no_user_srf; goto out_no_user_srf;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment