Received: by 10.213.65.68 with SMTP id h4csp838235imn; Tue, 27 Mar 2018 09:42:43 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+DYDFxQLm0ztCOwSEeCrDA/Q7sMKNtSgGUN7TSUxCFnYaigC3mKFVvSkOhqJ9z+X0qHlFL X-Received: by 2002:a17:902:d208:: with SMTP id t8-v6mr89702ply.6.1522168963400; Tue, 27 Mar 2018 09:42:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522168963; cv=none; d=google.com; s=arc-20160816; b=K8bKeLyoqyISVSgPnB4//J3Yn08IN/44o5nUAcnJvlY6TAJnUOmgRVvd6+N7ViG5z6 NZbHYLNfSr/2B0brwIjUjnfvqgsxGjN2SkI2/XP/Csjw7pNRenQJoPbUSRHjmsqhBSP8 +JZF0/+Roc16g7fDhIbOuFTzF6VAXt2hIRxkqg5Son+U/21oHVYaZl2wFEKKu46no3R8 qpTtmjo8zpWwhZCYc+VnN4szkPF/MOiVAyJjPO1Tc6yNzho9TyKo/fTJOHR016RYXZ/o +rGn28F6LyIVQcvNV/WBXMJ7b88kaVX9mJvTiNjWVP3XdXmTMrrZuSkaKUcnvnaK003T 7J1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=eeWm2Y6zv+bZYy2PLRwy/LOUok9GYPkXFc6OlgwaHYg=; b=HmXsv26WrtEHr5z8iE9VK4hHCTGSX4pT4JLEHEdg9T5xpaKiYPBtbsLbDIHv5udMQr b8scqvZpc2m5pr2xvIyQDUdPtLD912AQAdSjccqV5b0ujnANjsT12SjtTYBIu9ZswAjn 6Mx1/OSQVjb2PrUJlgMX4podeS12Uu/iM+/fe0oHNBCxP06fqfrjgvL44Hd1KyvIWvK1 kGa1wEeDbXHmw3Fib8Plxb9rOEwX6/JiYof0VuecG0dxegfSV28MxNbZmTW7f47vHo5Z Ng4xMJoT/I2v1LQ21za249fBKMIs6QYzMiIlhbVN+PF+f0HHWtNoT8iyzWXIpM3+PEkZ eayg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i21si1304196pfk.34.2018.03.27.09.42.29; Tue, 27 Mar 2018 09:42:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932472AbeC0Qk7 (ORCPT + 99 others); Tue, 27 Mar 2018 12:40:59 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:48530 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932459AbeC0Qk4 (ORCPT ); Tue, 27 Mar 2018 12:40:56 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 5B028D3B; Tue, 27 Mar 2018 16:40:55 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Thomas Hellstrom , Brian Paul , Sinclair Yeh Subject: [PATCH 4.15 056/105] drm/vmwgfx: Fix a destoy-while-held mutex problem. Date: Tue, 27 Mar 2018 18:27:36 +0200 Message-Id: <20180327162800.857416539@linuxfoundation.org> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180327162757.813009222@linuxfoundation.org> References: <20180327162757.813009222@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Thomas Hellstrom commit 73a88250b70954a8f27c2444e1c2411bba3c29d9 upstream. When validating legacy surfaces, the backup bo might be destroyed at surface validate time. However, the kms resource validation code may have the bo reserved, so we will destroy a locked mutex. While there shouldn't be any other users of that mutex when it is destroyed, it causes a lock leak and thus throws a lockdep error. Fix this by having the kms resource validation code hold a reference to the bo while we have it reserved. We do this by introducing a validation context which might come in handy when the kms code is extended to validate multiple resources or buffers. Cc: Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul Reviewed-by: Sinclair Yeh Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 28 +++++++++++++++++++--------- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 12 +++++++++--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 5 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 5 +++-- 4 files changed, 34 insertions(+), 16 deletions(-) --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -31,7 +31,6 @@ #include #include - /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) @@ -2531,9 +2530,12 @@ void vmw_kms_helper_buffer_finish(struct * Helper to be used if an error forces the caller to undo the actions of * vmw_kms_helper_resource_prepare. */ -void vmw_kms_helper_resource_revert(struct vmw_resource *res) +void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx) { - vmw_kms_helper_buffer_revert(res->backup); + struct vmw_resource *res = ctx->res; + + vmw_kms_helper_buffer_revert(ctx->buf); + vmw_dmabuf_unreference(&ctx->buf); vmw_resource_unreserve(res, false, NULL, 0); mutex_unlock(&res->dev_priv->cmdbuf_mutex); } @@ -2550,10 +2552,14 @@ void vmw_kms_helper_resource_revert(stru * interrupted by a signal. */ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, - bool interruptible) + bool interruptible, + struct vmw_validation_ctx *ctx) { int ret = 0; + ctx->buf = NULL; + ctx->res = res; + if (interruptible) ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex); else @@ -2572,6 +2578,8 @@ int vmw_kms_helper_resource_prepare(stru res->dev_priv->has_mob); if (ret) goto out_unreserve; + + ctx->buf = vmw_dmabuf_reference(res->backup); } ret = vmw_resource_validate(res); if (ret) @@ -2579,7 +2587,7 @@ int vmw_kms_helper_resource_prepare(stru return 0; out_revert: - vmw_kms_helper_buffer_revert(res->backup); + vmw_kms_helper_buffer_revert(ctx->buf); out_unreserve: vmw_resource_unreserve(res, false, NULL, 0); out_unlock: @@ -2595,11 +2603,13 @@ out_unlock: * @out_fence: Optional pointer to a fence pointer. If non-NULL, a * ref-counted fence pointer is returned here. */ -void vmw_kms_helper_resource_finish(struct vmw_resource *res, - struct vmw_fence_obj **out_fence) +void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, + struct vmw_fence_obj **out_fence) { - if (res->backup || out_fence) - vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup, + struct vmw_resource *res = ctx->res; + + if (ctx->buf || out_fence) + vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, out_fence, NULL); vmw_resource_unreserve(res, false, NULL, 0); --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -240,6 +240,11 @@ struct vmw_display_unit { int set_gui_y; }; +struct vmw_validation_ctx { + struct vmw_resource *res; + struct vmw_dma_buffer *buf; +}; + #define vmw_crtc_to_du(x) \ container_of(x, struct vmw_display_unit, crtc) #define vmw_connector_to_du(x) \ @@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct struct drm_vmw_fence_rep __user * user_fence_rep); int vmw_kms_helper_resource_prepare(struct vmw_resource *res, - bool interruptible); -void vmw_kms_helper_resource_revert(struct vmw_resource *res); -void vmw_kms_helper_resource_finish(struct vmw_resource *res, + bool interruptible, + struct vmw_validation_ctx *ctx); +void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx); +void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, struct vmw_fence_obj **out_fence); int vmw_kms_readback(struct vmw_private *dev_priv, struct drm_file *file_priv, --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct struct vmw_framebuffer_surface *vfbs = container_of(framebuffer, typeof(*vfbs), base); struct vmw_kms_sou_surface_dirty sdirty; + struct vmw_validation_ctx ctx; int ret; if (!srf) srf = &vfbs->surface->res; - ret = vmw_kms_helper_resource_prepare(srf, true); + ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); if (ret) return ret; @@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips, dest_x, dest_y, num_clips, inc, &sdirty.base); - vmw_kms_helper_resource_finish(srf, out_fence); + vmw_kms_helper_resource_finish(&ctx, out_fence); return ret; } --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vm struct vmw_framebuffer_surface *vfbs = container_of(framebuffer, typeof(*vfbs), base); struct vmw_stdu_dirty sdirty; + struct vmw_validation_ctx ctx; int ret; if (!srf) srf = &vfbs->surface->res; - ret = vmw_kms_helper_resource_prepare(srf, true); + ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); if (ret) return ret; @@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vm dest_x, dest_y, num_clips, inc, &sdirty.base); out_finish: - vmw_kms_helper_resource_finish(srf, out_fence); + vmw_kms_helper_resource_finish(&ctx, out_fence); return ret; }