From patchwork Tue Mar 25 13:19:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Hellstrom X-Patchwork-Id: 3887681 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4CF3E9F334 for ; Tue, 25 Mar 2014 13:19:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8F125201FD for ; Tue, 25 Mar 2014 13:19:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 86E352021C for ; Tue, 25 Mar 2014 13:19:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A51426E286; Tue, 25 Mar 2014 06:19:45 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp-outbound-1.vmware.com (smtp-outbound-1.vmware.com [208.91.2.12]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BEA46E283 for ; Tue, 25 Mar 2014 06:19:45 -0700 (PDT) Received: from sc9-mailhost1.vmware.com (sc9-mailhost1.vmware.com [10.113.161.71]) by smtp-outbound-1.vmware.com (Postfix) with ESMTP id 07CCA2812E for ; Tue, 25 Mar 2014 06:19:45 -0700 (PDT) Received: from zcs-prod-ext-mta-1.vmware.com (zcs-prod-ext-mta-1.vmware.com [10.113.62.223]) by sc9-mailhost1.vmware.com (Postfix) with ESMTP id 0458418364 for ; Tue, 25 Mar 2014 06:19:45 -0700 (PDT) Received: from zcs-prod-ext-mta-1.vmware.com (localhost.localdomain [127.0.0.1]) by zcs-prod-ext-mta-1.vmware.com (Postfix) with ESMTP id 34528120030; Tue, 25 Mar 2014 06:19:40 -0700 (PDT) Received: from ubuntu.localdomain (zimbra-prod-ext-proxy-vip.vmware.com [10.113.63.87]) by zcs-prod-ext-mta-1.vmware.com (Postfix) with ESMTPSA; Tue, 25 Mar 2014 06:19:38 -0700 (PDT) From: Thomas Hellstrom To: dri-devel@lists.freedesktop.org Subject: [PATCH 11/16] drm/vmwgfx: Allow prime fds in the surface reference ioctls Date: Tue, 25 Mar 2014 14:19:03 +0100 Message-Id: <1395753548-17441-12-git-send-email-thellstrom@vmware.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1395753548-17441-1-git-send-email-thellstrom@vmware.com> References: <1395753548-17441-1-git-send-email-thellstrom@vmware.com> Cc: pv-drivers@vmware.com, Thomas Hellstrom , linux-graphics-maintainer@vmware.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Allow prime fds and at the same time block legacy handles for render-nodes in the surface reference ioctls. This means these ioctls can be used directly from prime-aware clients, and that they can be called from render-nodes. Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul --- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 105 ++++++++++++++++++++----------- include/uapi/drm/vmwgfx_drm.h | 12 +++- 2 files changed, 81 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index aac243b..d50cd76 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -876,6 +876,64 @@ out_unlock: return ret; } + +static int +vmw_surface_handle_reference(struct vmw_private *dev_priv, + struct drm_file *file_priv, + uint32_t u_handle, + enum drm_vmw_handle_type handle_type, + struct ttm_base_object **base_p) +{ + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + uint32_t handle; + struct ttm_base_object *base; + int ret; + + 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; + } + handle = u_handle; + } + + ret = -EINVAL; + base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle); + if (unlikely(base == NULL)) { + DRM_ERROR("Could not find surface to reference.\n"); + goto out_no_lookup; + } + + if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) { + DRM_ERROR("Referenced object is not a surface.\n"); + goto out_bad_resource; + } + + if (handle_type != DRM_VMW_HANDLE_PRIME) { + ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not add a reference to a surface.\n"); + goto out_bad_resource; + } + } + + *base_p = base; + return 0; + +out_bad_resource: + ttm_base_object_unref(&base); +out_no_lookup: + if (handle_type == DRM_VMW_HANDLE_PRIME) + (void) ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); + + return ret; +} + /** * vmw_user_surface_define_ioctl - Ioctl function implementing * the user surface reference functionality. @@ -897,27 +955,16 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, struct vmw_user_surface *user_srf; struct drm_vmw_size __user *user_sizes; struct ttm_base_object *base; - int ret = -EINVAL; - - base = ttm_base_object_lookup_for_ref(dev_priv->tdev, req->sid); - if (unlikely(base == NULL)) { - DRM_ERROR("Could not find surface to reference.\n"); - return -EINVAL; - } + int ret; - if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) - goto out_bad_resource; + ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid, + req->handle_type, &base); + if (unlikely(ret != 0)) + return ret; user_srf = container_of(base, struct vmw_user_surface, prime.base); srf = &user_srf->srf; - ret = ttm_ref_object_add(tfile, &user_srf->prime.base, - TTM_REF_USAGE, NULL); - if (unlikely(ret != 0)) { - DRM_ERROR("Could not add a reference to a surface.\n"); - goto out_no_reference; - } - rep->flags = srf->flags; rep->format = srf->format; memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); @@ -930,10 +977,10 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, if (unlikely(ret != 0)) { DRM_ERROR("copy_to_user failed %p %u\n", user_sizes, srf->num_sizes); + ttm_ref_object_base_unref(tfile, base->hash.key, TTM_REF_USAGE); ret = -EFAULT; } -out_bad_resource: -out_no_reference: + ttm_base_object_unref(&base); return ret; @@ -1313,14 +1360,10 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, uint32_t backup_handle; int ret = -EINVAL; - base = ttm_base_object_lookup_for_ref(dev_priv->tdev, req->sid); - if (unlikely(base == NULL)) { - DRM_ERROR("Could not find surface to reference.\n"); - return -EINVAL; - } - - if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) - goto out_bad_resource; + ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid, + req->handle_type, &base); + if (unlikely(ret != 0)) + return ret; user_srf = container_of(base, struct vmw_user_surface, prime.base); srf = &user_srf->srf; @@ -1329,13 +1372,6 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, goto out_bad_resource; } - ret = ttm_ref_object_add(tfile, &user_srf->prime.base, - TTM_REF_USAGE, NULL); - if (unlikely(ret != 0)) { - DRM_ERROR("Could not add a reference to a GB surface.\n"); - goto out_bad_resource; - } - mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */ ret = vmw_user_dmabuf_reference(tfile, srf->res.backup, &backup_handle); @@ -1344,8 +1380,7 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, if (unlikely(ret != 0)) { DRM_ERROR("Could not add a reference to a GB surface " "backup buffer.\n"); - (void) ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, - req->sid, + (void) ttm_ref_object_base_unref(tfile, base->hash.key, TTM_REF_USAGE); goto out_bad_resource; } diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index 87792a5..4fc66f6 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -90,6 +90,15 @@ #define DRM_VMW_PARAM_MAX_MOB_SIZE 10 /** + * enum drm_vmw_handle_type - handle type for ref ioctls + * + */ +enum drm_vmw_handle_type { + DRM_VMW_HANDLE_LEGACY = 0, + DRM_VMW_HANDLE_PRIME = 1 +}; + +/** * struct drm_vmw_getparam_arg * * @value: Returned value. //Out @@ -177,6 +186,7 @@ struct drm_vmw_surface_create_req { * struct drm_wmv_surface_arg * * @sid: Surface id of created surface or surface to destroy or reference. + * @handle_type: Handle type for DRM_VMW_REF_SURFACE Ioctl. * * Output data from the DRM_VMW_CREATE_SURFACE Ioctl. * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl. @@ -185,7 +195,7 @@ struct drm_vmw_surface_create_req { struct drm_vmw_surface_arg { int32_t sid; - uint32_t pad64; + enum drm_vmw_handle_type handle_type; }; /**