diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 123 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fence.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 31 |
19 files changed, 194 insertions, 194 deletions
diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index fb7b82aad763..8c308dac99c5 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -1,6 +1,6 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" - depends on DRM && PCI && X86 + depends on DRM && PCI && X86 && MMU select FB_DEFERRED_IO select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h index 531d22025fec..babe7cb84fc2 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h @@ -980,6 +980,8 @@ svga3dsurface_get_mip_size(surf_size_struct base_level, u32 mip_level) size.width = max_t(u32, base_level.width >> mip_level, 1); size.height = max_t(u32, base_level.height >> mip_level, 1); size.depth = max_t(u32, base_level.depth >> mip_level, 1); + size.pad64 = 0; + return size; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c index 78b75ee3c931..4c7f24a67a2e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c @@ -825,6 +825,7 @@ static int vmw_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) * (currently only resources). */ static void vmw_move_notify(struct ttm_buffer_object *bo, + bool evict, struct ttm_mem_reg *mem) { vmw_resource_move_notify(bo, mem); @@ -839,7 +840,7 @@ static void vmw_move_notify(struct ttm_buffer_object *bo, */ static void vmw_swap_notify(struct ttm_buffer_object *bo) { - ttm_bo_wait(bo, false, false); + (void) ttm_bo_wait(bo, false, false); } @@ -849,6 +850,7 @@ struct ttm_bo_driver vmw_bo_driver = { .ttm_tt_unpopulate = &vmw_ttm_unpopulate, .invalidate_caches = vmw_invalidate_caches, .init_mem_type = vmw_init_mem_type, + .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = vmw_evict_flags, .move = NULL, .verify_access = vmw_verify_access, @@ -857,6 +859,4 @@ struct ttm_bo_driver vmw_bo_driver = { .fault_reserve_notify = &vmw_ttm_fault_reserve_notify, .io_mem_reserve = &vmw_ttm_io_mem_reserve, .io_mem_free = &vmw_ttm_io_mem_free, - .lru_tail = &ttm_bo_default_lru_tail, - .swap_lru_tail = &ttm_bo_default_swap_lru_tail, }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index aa04fb0159a7..77cb7c627e09 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -673,16 +673,10 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man, memset(info->node, 0, sizeof(*info->node)); spin_lock_bh(&man->lock); - ret = drm_mm_insert_node_generic(&man->mm, info->node, info->page_size, - 0, 0, - DRM_MM_SEARCH_DEFAULT, - DRM_MM_CREATE_DEFAULT); + ret = drm_mm_insert_node(&man->mm, info->node, info->page_size); if (ret) { vmw_cmdbuf_man_process(man); - ret = drm_mm_insert_node_generic(&man->mm, info->node, - info->page_size, 0, 0, - DRM_MM_SEARCH_DEFAULT, - DRM_MM_CREATE_DEFAULT); + ret = drm_mm_insert_node(&man->mm, info->node, info->page_size); } spin_unlock_bh(&man->lock); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 18061a4bc2f2..d08f26973d0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -199,9 +199,14 @@ static const struct drm_ioctl_desc vmw_ioctls[] = { VMW_IOCTL_DEF(VMW_PRESENT_READBACK, vmw_present_readback_ioctl, DRM_MASTER | DRM_AUTH), + /* + * The permissions of the below ioctl are overridden in + * vmw_generic_ioctl(). We require either + * DRM_MASTER or capable(CAP_SYS_ADMIN). + */ VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, - DRM_MASTER | DRM_CONTROL_ALLOW), + DRM_RENDER_ALLOW), VMW_IOCTL_DEF(VMW_CREATE_SHADER, vmw_shader_define_ioctl, DRM_AUTH | DRM_RENDER_ALLOW), @@ -951,7 +956,7 @@ out_err0: return ret; } -static int vmw_driver_unload(struct drm_device *dev) +static void vmw_driver_unload(struct drm_device *dev) { struct vmw_private *dev_priv = vmw_priv(dev); enum vmw_res_type i; @@ -998,8 +1003,6 @@ static int vmw_driver_unload(struct drm_device *dev) idr_destroy(&dev_priv->res_idr[i]); kfree(dev_priv); - - return 0; } static void vmw_postclose(struct drm_device *dev, @@ -1125,6 +1128,10 @@ static long vmw_generic_ioctl(struct file *filp, unsigned int cmd, return (long) vmw_execbuf_ioctl(dev, arg, file_priv, _IOC_SIZE(cmd)); + } else if (nr == DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT) { + if (!drm_is_current_master(file_priv) && + !capable(CAP_SYS_ADMIN)) + return -EACCES; } if (unlikely(ioctl->cmd != cmd)) @@ -1295,7 +1302,7 @@ static void __vmw_svga_enable(struct vmw_private *dev_priv) */ void vmw_svga_enable(struct vmw_private *dev_priv) { - ttm_read_lock(&dev_priv->reservation_sem, false); + (void) ttm_read_lock(&dev_priv->reservation_sem, false); __vmw_svga_enable(dev_priv); ttm_read_unlock(&dev_priv->reservation_sem); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1e59a486bba8..59ff4197173a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,9 +41,9 @@ #include <drm/ttm/ttm_module.h> #include "vmwgfx_fence.h" -#define VMWGFX_DRIVER_DATE "20160210" +#define VMWGFX_DRIVER_DATE "20170221" #define VMWGFX_DRIVER_MAJOR 2 -#define VMWGFX_DRIVER_MINOR 11 +#define VMWGFX_DRIVER_MINOR 12 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index d2d93959b119..e9005b9a5e8c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -83,7 +83,7 @@ static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, return 1; } - switch (par->set_fb->depth) { + switch (par->set_fb->format->depth) { case 24: case 32: pal[regno] = ((red & 0xff00) << 8) | @@ -91,8 +91,9 @@ static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, ((blue & 0xff00) >> 8); break; default: - DRM_ERROR("Bad depth %u, bpp %u.\n", par->set_fb->depth, - par->set_fb->bits_per_pixel); + DRM_ERROR("Bad depth %u, bpp %u.\n", + par->set_fb->format->depth, + par->set_fb->format->cpp[0] * 8); return 1; } @@ -197,7 +198,7 @@ static void vmw_fb_dirty_flush(struct work_struct *work) * Handle panning when copying from vmalloc to framebuffer. * Clip dirty area to framebuffer. */ - cpp = (cur_fb->bits_per_pixel + 7) / 8; + cpp = cur_fb->format->cpp[0]; max_x = par->fb_x + cur_fb->width; max_y = par->fb_y + cur_fb->height; @@ -465,33 +466,33 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, static int vmw_fb_kms_framebuffer(struct fb_info *info) { - struct drm_mode_fb_cmd mode_cmd; + struct drm_mode_fb_cmd2 mode_cmd; struct vmw_fb_par *par = info->par; struct fb_var_screeninfo *var = &info->var; struct drm_framebuffer *cur_fb; struct vmw_framebuffer *vfb; - int ret = 0; + int ret = 0, depth; size_t new_bo_size; - ret = vmw_fb_compute_depth(var, &mode_cmd.depth); + ret = vmw_fb_compute_depth(var, &depth); if (ret) return ret; mode_cmd.width = var->xres; mode_cmd.height = var->yres; - mode_cmd.bpp = var->bits_per_pixel; - mode_cmd.pitch = ((mode_cmd.bpp + 7) / 8) * mode_cmd.width; + mode_cmd.pitches[0] = ((var->bits_per_pixel + 7) / 8) * mode_cmd.width; + mode_cmd.pixel_format = + drm_mode_legacy_fb_format(var->bits_per_pixel, depth); cur_fb = par->set_fb; if (cur_fb && cur_fb->width == mode_cmd.width && cur_fb->height == mode_cmd.height && - cur_fb->bits_per_pixel == mode_cmd.bpp && - cur_fb->depth == mode_cmd.depth && - cur_fb->pitches[0] == mode_cmd.pitch) + cur_fb->format->format == mode_cmd.pixel_format && + cur_fb->pitches[0] == mode_cmd.pitches[0]) return 0; /* Need new buffer object ? */ - new_bo_size = (size_t) mode_cmd.pitch * (size_t) mode_cmd.height; + new_bo_size = (size_t) mode_cmd.pitches[0] * (size_t) mode_cmd.height; ret = vmw_fb_kms_detach(par, par->bo_size < new_bo_size || par->bo_size > 2*new_bo_size, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 26ac8e80a478..6b2708b4eafe 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -108,7 +108,7 @@ fman_from_fence(struct vmw_fence_obj *fence) * objects with actions attached to them. */ -static void vmw_fence_obj_destroy(struct fence *f) +static void vmw_fence_obj_destroy(struct dma_fence *f) { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); @@ -123,17 +123,17 @@ static void vmw_fence_obj_destroy(struct fence *f) fence->destroy(fence); } -static const char *vmw_fence_get_driver_name(struct fence *f) +static const char *vmw_fence_get_driver_name(struct dma_fence *f) { return "vmwgfx"; } -static const char *vmw_fence_get_timeline_name(struct fence *f) +static const char *vmw_fence_get_timeline_name(struct dma_fence *f) { return "svga"; } -static bool vmw_fence_enable_signaling(struct fence *f) +static bool vmw_fence_enable_signaling(struct dma_fence *f) { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); @@ -152,12 +152,12 @@ static bool vmw_fence_enable_signaling(struct fence *f) } struct vmwgfx_wait_cb { - struct fence_cb base; + struct dma_fence_cb base; struct task_struct *task; }; static void -vmwgfx_wait_cb(struct fence *fence, struct fence_cb *cb) +vmwgfx_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb) { struct vmwgfx_wait_cb *wait = container_of(cb, struct vmwgfx_wait_cb, base); @@ -167,7 +167,7 @@ vmwgfx_wait_cb(struct fence *fence, struct fence_cb *cb) static void __vmw_fences_update(struct vmw_fence_manager *fman); -static long vmw_fence_wait(struct fence *f, bool intr, signed long timeout) +static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout) { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); @@ -197,7 +197,7 @@ static long vmw_fence_wait(struct fence *f, bool intr, signed long timeout) while (ret > 0) { __vmw_fences_update(fman); - if (test_bit(FENCE_FLAG_SIGNALED_BIT, &f->flags)) + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags)) break; if (intr) @@ -225,7 +225,7 @@ out: return ret; } -static struct fence_ops vmw_fence_ops = { +static struct dma_fence_ops vmw_fence_ops = { .get_driver_name = vmw_fence_get_driver_name, .get_timeline_name = vmw_fence_get_timeline_name, .enable_signaling = vmw_fence_enable_signaling, @@ -298,7 +298,7 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) fman->event_fence_action_size = ttm_round_pot(sizeof(struct vmw_event_fence_action)); mutex_init(&fman->goal_irq_mutex); - fman->ctx = fence_context_alloc(1); + fman->ctx = dma_fence_context_alloc(1); return fman; } @@ -326,8 +326,8 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman, unsigned long irq_flags; int ret = 0; - fence_init(&fence->base, &vmw_fence_ops, &fman->lock, - fman->ctx, seqno); + dma_fence_init(&fence->base, &vmw_fence_ops, &fman->lock, + fman->ctx, seqno); INIT_LIST_HEAD(&fence->seq_passed_actions); fence->destroy = destroy; @@ -431,7 +431,7 @@ static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence) u32 goal_seqno; u32 *fifo_mem; - if (fence_is_signaled_locked(&fence->base)) + if (dma_fence_is_signaled_locked(&fence->base)) return false; fifo_mem = fman->dev_priv->mmio_virt; @@ -459,7 +459,7 @@ rerun: list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { if (seqno - fence->base.seqno < VMW_FENCE_WRAP) { list_del_init(&fence->head); - fence_signal_locked(&fence->base); + dma_fence_signal_locked(&fence->base); INIT_LIST_HEAD(&action_list); list_splice_init(&fence->seq_passed_actions, &action_list); @@ -500,18 +500,18 @@ bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence) { struct vmw_fence_manager *fman = fman_from_fence(fence); - if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) return 1; vmw_fences_update(fman); - return fence_is_signaled(&fence->base); + return dma_fence_is_signaled(&fence->base); } int vmw_fence_obj_wait(struct vmw_fence_obj *fence, bool lazy, bool interruptible, unsigned long timeout) { - long ret = fence_wait_timeout(&fence->base, interruptible, timeout); + long ret = dma_fence_wait_timeout(&fence->base, interruptible, timeout); if (likely(ret > 0)) return 0; @@ -530,7 +530,7 @@ void vmw_fence_obj_flush(struct vmw_fence_obj *fence) static void vmw_fence_destroy(struct vmw_fence_obj *fence) { - fence_free(&fence->base); + dma_fence_free(&fence->base); } int vmw_fence_create(struct vmw_fence_manager *fman, @@ -538,7 +538,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman, struct vmw_fence_obj **p_fence) { struct vmw_fence_obj *fence; - int ret; + int ret; fence = kzalloc(sizeof(*fence), GFP_KERNEL); if (unlikely(fence == NULL)) @@ -669,7 +669,7 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman) struct vmw_fence_obj *fence = list_entry(fman->fence_list.prev, struct vmw_fence_obj, head); - fence_get(&fence->base); + dma_fence_get(&fence->base); spin_unlock_irq(&fman->lock); ret = vmw_fence_obj_wait(fence, false, false, @@ -677,7 +677,7 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman) if (unlikely(ret != 0)) { list_del_init(&fence->head); - fence_signal(&fence->base); + dma_fence_signal(&fence->base); INIT_LIST_HEAD(&action_list); list_splice_init(&fence->seq_passed_actions, &action_list); @@ -685,7 +685,7 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman) } BUG_ON(!list_empty(&fence->head)); - fence_put(&fence->base); + dma_fence_put(&fence->base); spin_lock_irq(&fman->lock); } spin_unlock_irq(&fman->lock); @@ -701,6 +701,41 @@ void vmw_fence_fifo_up(struct vmw_fence_manager *fman) } +/** + * vmw_fence_obj_lookup - Look up a user-space fence object + * + * @tfile: A struct ttm_object_file identifying the caller. + * @handle: A handle identifying the fence object. + * @return: A struct vmw_user_fence base ttm object on success or + * an error pointer on failure. + * + * The fence object is looked up and type-checked. The caller needs + * to have opened the fence object first, but since that happens on + * creation and fence objects aren't shareable, that's not an + * issue currently. + */ +static struct ttm_base_object * +vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle) +{ + struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle); + + if (!base) { + pr_err("Invalid fence object handle 0x%08lx.\n", + (unsigned long)handle); + return ERR_PTR(-EINVAL); + } + + if (base->refcount_release != vmw_user_fence_base_release) { + pr_err("Invalid fence object handle 0x%08lx.\n", + (unsigned long)handle); + ttm_base_object_unref(&base); + return ERR_PTR(-EINVAL); + } + + return base; +} + + int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -726,13 +761,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, arg->kernel_cookie = jiffies + wait_timeout; } - base = ttm_base_object_lookup(tfile, arg->handle); - if (unlikely(base == NULL)) { - printk(KERN_ERR "Wait invalid fence object handle " - "0x%08lx.\n", - (unsigned long)arg->handle); - return -EINVAL; - } + base = vmw_fence_obj_lookup(tfile, arg->handle); + if (IS_ERR(base)) + return PTR_ERR(base); fence = &(container_of(base, struct vmw_user_fence, base)->fence); @@ -771,13 +802,9 @@ int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data, struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_private *dev_priv = vmw_priv(dev); - base = ttm_base_object_lookup(tfile, arg->handle); - if (unlikely(base == NULL)) { - printk(KERN_ERR "Fence signaled invalid fence object handle " - "0x%08lx.\n", - (unsigned long)arg->handle); - return -EINVAL; - } + base = vmw_fence_obj_lookup(tfile, arg->handle); + if (IS_ERR(base)) + return PTR_ERR(base); fence = &(container_of(base, struct vmw_user_fence, base)->fence); fman = fman_from_fence(fence); @@ -884,7 +911,7 @@ static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence, spin_lock_irqsave(&fman->lock, irq_flags); fman->pending_actions[action->type]++; - if (fence_is_signaled_locked(&fence->base)) { + if (dma_fence_is_signaled_locked(&fence->base)) { struct list_head action_list; INIT_LIST_HEAD(&action_list); @@ -1024,6 +1051,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, (struct drm_vmw_fence_event_arg *) data; struct vmw_fence_obj *fence = NULL; struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); + struct ttm_object_file *tfile = vmw_fp->tfile; struct drm_vmw_fence_rep __user *user_fence_rep = (struct drm_vmw_fence_rep __user *)(unsigned long) arg->fence_rep; @@ -1037,24 +1065,18 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, */ if (arg->handle) { struct ttm_base_object *base = - ttm_base_object_lookup_for_ref(dev_priv->tdev, - arg->handle); - - if (unlikely(base == NULL)) { - DRM_ERROR("Fence event invalid fence object handle " - "0x%08lx.\n", - (unsigned long)arg->handle); - return -EINVAL; - } + vmw_fence_obj_lookup(tfile, arg->handle); + + if (IS_ERR(base)) + return PTR_ERR(base); + fence = &(container_of(base, struct vmw_user_fence, base)->fence); (void) vmw_fence_obj_reference(fence); if (user_fence_rep != NULL) { - bool existed; - ret = ttm_ref_object_add(vmw_fp->tfile, base, - TTM_REF_USAGE, &existed); + TTM_REF_USAGE, NULL, false); if (unlikely(ret != 0)) { DRM_ERROR("Failed to reference a fence " "object.\n"); @@ -1097,8 +1119,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, return 0; out_no_create: if (user_fence_rep != NULL) - ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, - handle, TTM_REF_USAGE); + ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); out_no_ref_obj: vmw_fence_obj_unreference(&fence); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h index 83ae301ee141..d9d85aa6ed20 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h @@ -27,7 +27,7 @@ #ifndef _VMWGFX_FENCE_H_ -#include <linux/fence.h> +#include <linux/dma-fence.h> #define VMW_FENCE_WAIT_TIMEOUT (5*HZ) @@ -52,7 +52,7 @@ struct vmw_fence_action { }; struct vmw_fence_obj { - struct fence base; + struct dma_fence base; struct list_head head; struct list_head seq_passed_actions; @@ -71,14 +71,14 @@ vmw_fence_obj_unreference(struct vmw_fence_obj **fence_p) *fence_p = NULL; if (fence) - fence_put(&fence->base); + dma_fence_put(&fence->base); } static inline struct vmw_fence_obj * vmw_fence_obj_reference(struct vmw_fence_obj *fence) { if (fence) - fence_get(&fence->base); + dma_fence_get(&fence->base); return fence; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index 170b61be1e4e..fec7348cea2c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -164,9 +164,9 @@ static void vmw_gmrid_man_debug(struct ttm_mem_type_manager *man, } const struct ttm_mem_type_manager_func vmw_gmrid_manager_func = { - vmw_gmrid_man_init, - vmw_gmrid_man_takedown, - vmw_gmrid_man_get_node, - vmw_gmrid_man_put_node, - vmw_gmrid_man_debug + .init = vmw_gmrid_man_init, + .takedown = vmw_gmrid_man_takedown, + .get_node = vmw_gmrid_man_get_node, + .put_node = vmw_gmrid_man_put_node, + .debug = vmw_gmrid_man_debug }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index b8c6a03c8c54..5ec24fd801cd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -114,8 +114,6 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, param->value = dev_priv->has_dx; break; default: - DRM_ERROR("Illegal vmwgfx get param request: %d\n", - param->param); return -EINVAL; } @@ -186,7 +184,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); - if (unlikely(arg->pad64 != 0)) { + if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { DRM_ERROR("Illegal GET_3D_CAP argument.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index bf28ccc150df..d492d57d5309 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -516,7 +516,7 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = { static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, struct vmw_surface *surface, struct vmw_framebuffer **out, - const struct drm_mode_fb_cmd + const struct drm_mode_fb_cmd2 *mode_cmd, bool is_dmabuf_proxy) @@ -525,6 +525,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, struct vmw_framebuffer_surface *vfbs; enum SVGA3dSurfaceFormat format; int ret; + struct drm_format_name_buf format_name; /* 3D is only supported on HWv8 and newer hosts */ if (dev_priv->active_display_unit == vmw_du_legacy) @@ -548,21 +549,22 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, return -EINVAL; } - switch (mode_cmd->depth) { - case 32: + switch (mode_cmd->pixel_format) { + case DRM_FORMAT_ARGB8888: format = SVGA3D_A8R8G8B8; break; - case 24: + case DRM_FORMAT_XRGB8888: format = SVGA3D_X8R8G8B8; break; - case 16: + case DRM_FORMAT_RGB565: format = SVGA3D_R5G6B5; break; - case 15: + case DRM_FORMAT_XRGB1555: format = SVGA3D_A1R5G5B5; break; default: - DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth); + DRM_ERROR("Invalid pixel format: %s\n", + drm_get_format_name(mode_cmd->pixel_format, &format_name)); return -EINVAL; } @@ -581,14 +583,9 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, goto out_err1; } - /* XXX get the first 3 from the surface info */ - vfbs->base.base.bits_per_pixel = mode_cmd->bpp; - vfbs->base.base.pitches[0] = mode_cmd->pitch; - vfbs->base.base.depth = mode_cmd->depth; - vfbs->base.base.width = mode_cmd->width; - vfbs->base.base.height = mode_cmd->height; + drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd); vfbs->surface = vmw_surface_reference(surface); - vfbs->base.user_handle = mode_cmd->handle; + vfbs->base.user_handle = mode_cmd->handles[0]; vfbs->is_dmabuf_proxy = is_dmabuf_proxy; *out = &vfbs->base; @@ -755,25 +752,26 @@ static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb) * 0 on success, error code otherwise */ static int vmw_create_dmabuf_proxy(struct drm_device *dev, - const struct drm_mode_fb_cmd *mode_cmd, + const struct drm_mode_fb_cmd2 *mode_cmd, struct vmw_dma_buffer *dmabuf_mob, struct vmw_surface **srf_out) { uint32_t format; - struct drm_vmw_size content_base_size; + struct drm_vmw_size content_base_size = {0}; struct vmw_resource *res; unsigned int bytes_pp; + struct drm_format_name_buf format_name; int ret; - switch (mode_cmd->depth) { - case 32: - case 24: + switch (mode_cmd->pixel_format) { + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: format = SVGA3D_X8R8G8B8; bytes_pp = 4; break; - case 16: - case 15: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: format = SVGA3D_R5G6B5; bytes_pp = 2; break; @@ -784,11 +782,12 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev, break; default: - DRM_ERROR("Invalid framebuffer format %d\n", mode_cmd->depth); + DRM_ERROR("Invalid framebuffer format %s\n", + drm_get_format_name(mode_cmd->pixel_format, &format_name)); return -EINVAL; } - content_base_size.width = mode_cmd->pitch / bytes_pp; + content_base_size.width = mode_cmd->pitches[0] / bytes_pp; content_base_size.height = mode_cmd->height; content_base_size.depth = 1; @@ -826,16 +825,17 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev, static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, struct vmw_dma_buffer *dmabuf, struct vmw_framebuffer **out, - const struct drm_mode_fb_cmd + const struct drm_mode_fb_cmd2 *mode_cmd) { struct drm_device *dev = dev_priv->dev; struct vmw_framebuffer_dmabuf *vfbd; unsigned int requested_size; + struct drm_format_name_buf format_name; int ret; - requested_size = mode_cmd->height * mode_cmd->pitch; + requested_size = mode_cmd->height * mode_cmd->pitches[0]; if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) { DRM_ERROR("Screen buffer object size is too small " "for requested mode.\n"); @@ -844,27 +844,16 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, /* Limited framebuffer color depth support for screen objects */ if (dev_priv->active_display_unit == vmw_du_screen_object) { - switch (mode_cmd->depth) { - case 32: - case 24: - /* Only support 32 bpp for 32 and 24 depth fbs */ - if (mode_cmd->bpp == 32) - break; - - DRM_ERROR("Invalid color depth/bbp: %d %d\n", - mode_cmd->depth, mode_cmd->bpp); - return -EINVAL; - case 16: - case 15: - /* Only support 16 bpp for 16 and 15 depth fbs */ - if (mode_cmd->bpp == 16) - break; - - DRM_ERROR("Invalid color depth/bbp: %d %d\n", - mode_cmd->depth, mode_cmd->bpp); - return -EINVAL; + switch (mode_cmd->pixel_format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + break; + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_RGB565: + break; default: - DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth); + DRM_ERROR("Invalid pixel format: %s\n", + drm_get_format_name(mode_cmd->pixel_format, &format_name)); return -EINVAL; } } @@ -875,14 +864,10 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, goto out_err1; } - vfbd->base.base.bits_per_pixel = mode_cmd->bpp; - vfbd->base.base.pitches[0] = mode_cmd->pitch; - vfbd->base.base.depth = mode_cmd->depth; - vfbd->base.base.width = mode_cmd->width; - vfbd->base.base.height = mode_cmd->height; + drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd); vfbd->base.dmabuf = true; vfbd->buffer = vmw_dmabuf_reference(dmabuf); - vfbd->base.user_handle = mode_cmd->handle; + vfbd->base.user_handle = mode_cmd->handles[0]; *out = &vfbd->base; ret = drm_framebuffer_init(dev, &vfbd->base.base, @@ -916,7 +901,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, struct vmw_dma_buffer *dmabuf, struct vmw_surface *surface, bool only_2d, - const struct drm_mode_fb_cmd *mode_cmd) + const struct drm_mode_fb_cmd2 *mode_cmd) { struct vmw_framebuffer *vfb = NULL; bool is_dmabuf_proxy = false; @@ -971,7 +956,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, struct drm_file *file_priv, - const struct drm_mode_fb_cmd2 *mode_cmd2) + const struct drm_mode_fb_cmd2 *mode_cmd) { struct vmw_private *dev_priv = vmw_priv(dev); struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; @@ -979,16 +964,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, struct vmw_surface *surface = NULL; struct vmw_dma_buffer *bo = NULL; struct ttm_base_object *user_obj; - struct drm_mode_fb_cmd mode_cmd; int ret; - mode_cmd.width = mode_cmd2->width; - mode_cmd.height = mode_cmd2->height; - mode_cmd.pitch = mode_cmd2->pitches[0]; - mode_cmd.handle = mode_cmd2->handles[0]; - drm_fb_get_bpp_depth(mode_cmd2->pixel_format, &mode_cmd.depth, - &mode_cmd.bpp); - /** * This code should be conditioned on Screen Objects not being used. * If screen objects are used, we can allocate a GMR to hold the @@ -996,8 +973,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, */ if (!vmw_kms_validate_mode_vram(dev_priv, - mode_cmd.pitch, - mode_cmd.height)) { + mode_cmd->pitches[0], + mode_cmd->height)) { DRM_ERROR("Requested mode exceed bounding box limit.\n"); return ERR_PTR(-ENOMEM); } @@ -1011,7 +988,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, * command stream using user-space handles. */ - user_obj = ttm_base_object_lookup(tfile, mode_cmd.handle); + user_obj = ttm_base_object_lookup(tfile, mode_cmd->handles[0]); if (unlikely(user_obj == NULL)) { DRM_ERROR("Could not locate requested kms frame buffer.\n"); return ERR_PTR(-ENOENT); @@ -1023,14 +1000,14 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, /* returns either a dmabuf or surface */ ret = vmw_user_lookup_handle(dev_priv, tfile, - mode_cmd.handle, + mode_cmd->handles[0], &surface, &bo); if (ret) goto err_out; vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface, !(dev_priv->capabilities & SVGA_CAP_3D), - &mode_cmd); + mode_cmd); if (IS_ERR(vfb)) { ret = PTR_ERR(vfb); goto err_out; @@ -1694,7 +1671,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, * 1. Bounding box (assuming 32bpp) must be < prim_bb_mem * 2. Total pixels (assuming 32bpp) must be < prim_bb_mem */ - u64 bb_mem = bounding_box.w * bounding_box.h * 4; + u64 bb_mem = (u64) bounding_box.w * bounding_box.h * 4; u64 pixel_mem = total_pixels * 4; if (bb_mem > dev_priv->prim_bb_mem) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index ff4803c107bc..cb36e1d70133 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -30,6 +30,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_encoder.h> #include "vmwgfx_drv.h" /** @@ -248,7 +249,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, struct vmw_dma_buffer *dmabuf, struct vmw_surface *surface, bool only_2d, - const struct drm_mode_fb_cmd *mode_cmd); + const struct drm_mode_fb_cmd2 *mode_cmd); int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, unsigned unit, u32 max_width, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 23ec673d5e16..3806148e1bdb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -97,7 +97,8 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) fb = entry->base.crtc.primary->fb; return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], - fb->bits_per_pixel, fb->depth); + fb->format->cpp[0] * 8, + fb->format->depth); } if (!list_empty(&lds->active)) { @@ -105,7 +106,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) fb = entry->base.crtc.primary->fb; vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitches[0], - fb->bits_per_pixel, fb->depth); + fb->format->cpp[0] * 8, fb->format->depth); } /* Make sure we always show something. */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index b6126a5f1269..941bcfd131ff 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -319,18 +319,17 @@ int vmw_otables_setup(struct vmw_private *dev_priv) int ret; if (dev_priv->has_dx) { - *otables = kmalloc(sizeof(dx_tables), GFP_KERNEL); + *otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL); if (*otables == NULL) return -ENOMEM; - memcpy(*otables, dx_tables, sizeof(dx_tables)); dev_priv->otable_batch.num_otables = ARRAY_SIZE(dx_tables); } else { - *otables = kmalloc(sizeof(pre_dx_tables), GFP_KERNEL); + *otables = kmemdup(pre_dx_tables, sizeof(pre_dx_tables), + GFP_KERNEL); if (*otables == NULL) return -ENOMEM; - memcpy(*otables, pre_dx_tables, sizeof(pre_dx_tables)); dev_priv->otable_batch.num_otables = ARRAY_SIZE(pre_dx_tables); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 52ca1c9d070e..bf23153d4f55 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -575,7 +575,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, long lret; lret = reservation_object_wait_timeout_rcu(bo->resv, true, true, - nonblock ? 0 : MAX_SCHEDULE_TIMEOUT); + nonblock ? 0 : MAX_SCHEDULE_TIMEOUT); if (!lret) return -EBUSY; else if (lret < 0) @@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, return ret; ret = ttm_ref_object_add(tfile, &user_bo->prime.base, - TTM_REF_SYNCCPU_WRITE, &existed); + TTM_REF_SYNCCPU_WRITE, &existed, false); if (ret != 0 || existed) ttm_bo_synccpu_write_release(&user_bo->dma.base); @@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile, *handle = user_bo->prime.base.hash.key; return ttm_ref_object_add(tfile, &user_bo->prime.base, - TTM_REF_USAGE, NULL); + TTM_REF_USAGE, NULL, false); } /* @@ -1454,7 +1454,7 @@ void vmw_fence_single_bo(struct ttm_buffer_object *bo, if (fence == NULL) { vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); reservation_object_add_excl_fence(bo->resv, &fence->base); - fence_put(&fence->base); + dma_fence_put(&fence->base); } else reservation_object_add_excl_fence(bo->resv, &fence->base); } @@ -1760,7 +1760,7 @@ void vmw_resource_unpin(struct vmw_resource *res) struct vmw_private *dev_priv = res->dev_priv; int ret; - ttm_read_lock(&dev_priv->reservation_sem, false); + (void) ttm_read_lock(&dev_priv->reservation_sem, false); mutex_lock(&dev_priv->cmdbuf_mutex); ret = vmw_resource_reserve(res, false, true); @@ -1770,7 +1770,7 @@ void vmw_resource_unpin(struct vmw_resource *res) if (--res->pin_count == 0 && res->backup) { struct vmw_dma_buffer *vbo = res->backup; - ttm_bo_reserve(&vbo->base, false, false, NULL); + (void) ttm_bo_reserve(&vbo->base, false, false, NULL); vmw_bo_pin_reserved(vbo, false); ttm_bo_unreserve(&vbo->base); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index f42359084adc..d4268efc37d2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -598,7 +598,7 @@ static int do_dmabuf_define_gmrfb(struct vmw_private *dev_priv, struct vmw_dma_buffer *buf = container_of(framebuffer, struct vmw_framebuffer_dmabuf, base)->buffer; - int depth = framebuffer->base.depth; + int depth = framebuffer->base.format->depth; struct { uint32_t header; SVGAFifoCmdDefineGMRFB body; @@ -618,7 +618,7 @@ static int do_dmabuf_define_gmrfb(struct vmw_private *dev_priv, } cmd->header = SVGA_CMD_DEFINE_GMRFB; - cmd->body.format.bitsPerPixel = framebuffer->base.bits_per_pixel; + cmd->body.format.bitsPerPixel = framebuffer->base.format->cpp[0] * 8; cmd->body.format.colorDepth = depth; cmd->body.format.reserved = 0; cmd->body.bytesPerLine = framebuffer->base.pitches[0]; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 94ad8d2acf9a..b27cd18ee66a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -424,7 +424,7 @@ static int vmw_stdu_bind_fb(struct vmw_private *dev_priv, */ if (new_content_type == SEPARATE_DMA) { - switch (new_fb->bits_per_pixel) { + switch (new_fb->format->cpp[0] * 8) { case 32: content_srf.format = SVGA3D_X8R8G8B8; break; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index b445ce9b9757..05fa092c942b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -713,11 +713,14 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, 128; num_sizes = 0; - for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) + for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { + if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS) + return -EINVAL; num_sizes += req->mip_levels[i]; + } - if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * - DRM_VMW_MAX_MIP_LEVELS) + if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS || + num_sizes == 0) return -EINVAL; size = vmw_user_surface_size + 128 + @@ -891,17 +894,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, uint32_t handle; struct ttm_base_object *base; int ret; + bool require_exist = false; if (handle_type == DRM_VMW_HANDLE_PRIME) { ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle); if (unlikely(ret != 0)) return ret; } else { - if (unlikely(drm_is_render_client(file_priv))) { - DRM_ERROR("Render client refused legacy " - "surface reference.\n"); - return -EACCES; - } + if (unlikely(drm_is_render_client(file_priv))) + require_exist = true; + if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) { DRM_ERROR("Locked master refused legacy " "surface reference.\n"); @@ -929,17 +931,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, /* * Make sure the surface creator has the same - * authenticating master. + * authenticating master, or is already registered with us. */ if (drm_is_primary_client(file_priv) && - user_srf->master != file_priv->master) { - DRM_ERROR("Trying to reference surface outside of" - " master domain.\n"); - ret = -EACCES; - goto out_bad_resource; - } + user_srf->master != file_priv->master) + require_exist = true; - ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); + ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, + require_exist); if (unlikely(ret != 0)) { DRM_ERROR("Could not add a reference to a surface.\n"); goto out_bad_resource; |