Received: by 2002:a05:6358:489b:b0:bb:da1:e618 with SMTP id x27csp6918278rwn; Tue, 13 Sep 2022 10:49:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5ao51F76DWbOT14tl/p+80+kbMWatPr0829gfoPpvOycEfbPUF/kW9VFLJ6UpmlTESONgo X-Received: by 2002:a17:90b:4a82:b0:200:a89e:6f1f with SMTP id lp2-20020a17090b4a8200b00200a89e6f1fmr403487pjb.13.1663091387300; Tue, 13 Sep 2022 10:49:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663091387; cv=none; d=google.com; s=arc-20160816; b=bd5DOr0iArJ4K6vN6hy4Jaag9n8HO9eb0B9356t0l/HyfeFA2V5JwIMnGZ/ebh4R3D LUgPnZoDcjazLqyoVrA2kX6D736Fo8PtTjA8phSD6xaNETFOaZoO+uEK5/H53Am2lTlR wrMgagS5RxHFNYJ4Y1sXQ0STaF1TNrsveXe+1y7gAa7VBWe99SRsGjyVuUmEyydAU4z7 iP8TaQyDbc7aOmM5W1+iPSuYdKWfn5nwMHZY6WCNx/mCztne5LtF1VIXq/VxbQZ4halY 7abnHaKMB9zwD2PumzOBP3ISHV7Flg7/AZGKnijlP8Qu5MconB4ixAmzn/ms62rOUcsL EIhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=H7ZDtAsHLo6EqccgDMDK6z4lQxZsv8M5HK/26cncGy0=; b=nVav5gaVyPp8W988BkwNyoNQ3RUO/x1IDyB++ydY2934UWDR3VDWHXD+Bl/0xZaHBc mHTX7FE2Ku9zHUA1gd4gWMG5J3rIWf3uSQZhtQy3BuaOvYkoLW4zRfhxD8wXDgXEfGVG yfBbk6dcxcSBLMMfsodn3RjuQEx2oQtZ++ulhgavwCl8ZefawE5QrVA8ccO+K0Slpr08 yFaoqFkhJvCw/Q9dRQ4bBOD6dLCUInetxRr1Ta+J8DfEtObz7n+rqbEdSY34LYxeKBtb a8PpDC7A3KZ0ZBIwNQ13gimeg8RwIZI+cUqfboh1eTKM5oD8uRmaY5rj1pBuOcWzmeN2 MBSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=F7x+CXd8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id om18-20020a17090b3a9200b00202d32866e8si6893980pjb.88.2022.09.13.10.49.32; Tue, 13 Sep 2022 10:49:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=F7x+CXd8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232623AbiIMRTA (ORCPT + 99 others); Tue, 13 Sep 2022 13:19:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232548AbiIMRR6 (ORCPT ); Tue, 13 Sep 2022 13:17:58 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB6127F0B0; Tue, 13 Sep 2022 09:05:19 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id DA2FDB80F98; Tue, 13 Sep 2022 14:27:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3CFD6C433C1; Tue, 13 Sep 2022 14:27:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1663079267; bh=+B/deXk8yVP4vKZULyveQWzafq6t/dXHKfPkuAy3W3E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F7x+CXd8ssNvnTTyLpXYvOOlTF4Kg3EzG9zoEBSrPagWuZpDVCIEs3ollClklGcUa TOJDDXoYz9kdI8WA762ysEjdDHAE78Opw9LiDl9z9N8jdkqc86nrxN0d2viPCBwvXZ sAcgrdbpVakJ+cz7RKlwJKiie2pe+KFOZfbwboLo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jeffy Chen , =?UTF-8?q?Christian=20K=C3=B6nig?= , Sasha Levin Subject: [PATCH 5.4 068/108] drm/gem: Fix GEM handle release errors Date: Tue, 13 Sep 2022 16:06:39 +0200 Message-Id: <20220913140356.541357102@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220913140353.549108748@linuxfoundation.org> References: <20220913140353.549108748@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jeffy Chen [ Upstream commit ea2aa97ca37a9044ade001aef71dbc06318e8d44 ] Currently we are assuming a one to one mapping between dmabuf and GEM handle when releasing GEM handles. But that is not always true, since we would create extra handles for the GEM obj in cases like gem_open() and getfb{,2}(). A similar issue was reported at: https://lore.kernel.org/all/20211105083308.392156-1-jay.xu@rock-chips.com/ Another problem is that the imported dmabuf might not always have gem_obj->dma_buf set, which would cause leaks in drm_gem_remove_prime_handles(). Let's fix these for now by using handle to find the exact map to remove. Signed-off-by: Jeffy Chen Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20220819072834.17888-1-jeffy.chen@rock-chips.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_gem.c | 17 +---------------- drivers/gpu/drm/drm_internal.h | 4 ++-- drivers/gpu/drm/drm_prime.c | 20 ++++++++++++-------- 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 25a2d80287d67..d6a72f3cb1fbd 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -167,21 +167,6 @@ void drm_gem_private_object_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_gem_private_object_init); -static void -drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) -{ - /* - * Note: obj->dma_buf can't disappear as long as we still hold a - * handle reference in obj->handle_count. - */ - mutex_lock(&filp->prime.lock); - if (obj->dma_buf) { - drm_prime_remove_buf_handle_locked(&filp->prime, - obj->dma_buf); - } - mutex_unlock(&filp->prime.lock); -} - /** * drm_gem_object_handle_free - release resources bound to userspace handles * @obj: GEM object to clean up. @@ -255,7 +240,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) else if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); - drm_gem_remove_prime_handles(obj, file_priv); + drm_prime_remove_buf_handle(&file_priv->prime, id); drm_vma_node_revoke(&obj->vma_node, file_priv); drm_gem_object_handle_put_unlocked(obj); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 51a2055c8f18a..41a9a9bae5848 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -59,8 +59,8 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); -void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf); +void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, + uint32_t handle); /* drm_drv.c */ struct drm_minor *drm_minor_acquire(unsigned int minor_id); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0a2316e0e8121..6b7cf0170f9d1 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -187,29 +187,33 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri return -ENOENT; } -void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf) +void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, + uint32_t handle) { struct rb_node *rb; - rb = prime_fpriv->dmabufs.rb_node; + mutex_lock(&prime_fpriv->lock); + + rb = prime_fpriv->handles.rb_node; while (rb) { struct drm_prime_member *member; - member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); - if (member->dma_buf == dma_buf) { + member = rb_entry(rb, struct drm_prime_member, handle_rb); + if (member->handle == handle) { rb_erase(&member->handle_rb, &prime_fpriv->handles); rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); - dma_buf_put(dma_buf); + dma_buf_put(member->dma_buf); kfree(member); - return; - } else if (member->dma_buf < dma_buf) { + break; + } else if (member->handle < handle) { rb = rb->rb_right; } else { rb = rb->rb_left; } } + + mutex_unlock(&prime_fpriv->lock); } void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) -- 2.35.1