| Message ID | 20260814203542.1405135-6-lyude@redhat.com (mailing list archive) |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-sunxi+bounces-25181-sunxi=pue.re@lists.linux.dev> X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id BE5061C0100 for <noreply@patchwork.local>; Fri, 14 Aug 2026 22:38:21 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=redhat.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-25181-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-25181-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 1C1C93053DE8 for <noreply@patchwork.local>; Fri, 14 Aug 2026 20:36:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E349239020C; Fri, 14 Aug 2026 20:36:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Lh3qfUZ4" X-Original-To: linux-sunxi@lists.linux.dev Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D2CBD3DD521 for <linux-sunxi@lists.linux.dev>; Fri, 14 Aug 2026 20:36:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786739776; cv=none; b=nsj3yiYwOznpxNGOyyy/CAfxQmFQ/Ke7wu3u5tgygwI+kZ0/pdO7bWkFlyQ0eU2f6vojTtg4yzzrNmGYbkKIabMA6YqMnlOSkYptDv2vcRVMLC9/h3lz+mRRNmnoREhJitixgZZa63NcOADPRGRyqA1MGkza2gs713Pck5Ab25M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786739776; c=relaxed/simple; bh=vmm1i0C9vXfD/IrBSW0vxZDHe7jpxrPQHihUJzNbwdo=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=mUJj01+fAKmOivUAdlzIpyNk8SWVvhvArBQ16cBwEJ0NWvhMd4rDjqKofmGzeNpchn/tSD5+kxPfuH2uyQMctb2IsYUTkaHs09OFKVmNzAVlZny2PuIevjOwA3Dv+kUu1qBy4B5CmYFUq+BLaGvuBWHI030ikikezaqT1RyTUzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Lh3qfUZ4; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1786739774; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WquuCq3TQCd+s4bFYX3uFmTk9vt6sijgW3Z8EuiR4qM=; b=Lh3qfUZ4M8FKABwImIYuTYp403JKQ5WBgNtCnMAE9RGIktKUG2mtXm1V4IkQlEtG2mWvCd +7aQF8q37jwEOa1YzcXCgQ1TgV4f1bkzA8e9mGlimJI5JpwWuWPeXz9IItTzX5yHwwBnf5 t9P59Efwschtb++Vpe1whieqVayB7mA= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-495-3lqovXAqMhKKYoeTKCS2Bg-1; Fri, 14 Aug 2026 16:36:10 -0400 X-MC-Unique: 3lqovXAqMhKKYoeTKCS2Bg-1 X-Mimecast-MFC-AGG-ID: 3lqovXAqMhKKYoeTKCS2Bg_1786739767 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A467E1956069; Fri, 14 Aug 2026 20:36:07 +0000 (UTC) Received: from GoldenWind.lan (unknown [10.22.64.233]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BFE71197750F; Fri, 14 Aug 2026 20:36:04 +0000 (UTC) From: Lyude Paul <lyude@redhat.com> To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, freedreno@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, nouveau@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-sunxi@lists.linux.dev, asahi@lists.linux.dev, linux-stm32@st-md-mailman.stormreply.com, linux-samsung-soc@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-mediatek@lists.infradead.org, intel-gfx@lists.freedesktop.org, linux-aspeed@lists.ozlabs.org, linux-rockchip@lists.infradead.org, linux-tegra@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-mips@vger.kernel.org, amd-gfx@lists.freedesktop.org, spice-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org, imx@lists.linux.dev Subject: [PATCH 5/5] drm/vblank: Require all CRTCs implement vblank support in drm_vblank_init() Date: Fri, 14 Aug 2026 16:35:33 -0400 Message-ID: <20260814203542.1405135-6-lyude@redhat.com> In-Reply-To: <20260814203542.1405135-1-lyude@redhat.com> References: <20260814203542.1405135-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: <linux-sunxi.lists.linux.dev> List-Subscribe: <mailto:linux-sunxi+subscribe@lists.linux.dev> List-Unsubscribe: <mailto:linux-sunxi+unsubscribe@lists.linux.dev> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-MFC-PROC-ID: CJXr4bK--JKrlzIdvOc2oBYDD0iZLBPsMRWtUsh5Q1Q_1786739767 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= |
| Series |
drm/vblank: Enforce all-or-nothing vblank support
|
|
Commit Message
Lyude Paul
Aug. 14, 2026, 8:35 p.m. UTC
Due to us previously allowing users to specify the number of CRTCs for
drm_vblank_init() manually, a untested and almost certainly UB edge case
was technically possible for drivers: implementing vblank support for some
of their CRTCs, and not implementing it for others.
I don't think there's any actual situation in the real world where hardware
like this exists, nor do I think supporting such a possibility was ever
actually the original intent here. But in Rust, we need to be able to
prevent such a situation from occurring since we cannot guarantee no UB is
possible otherwise. I think it makes sense here for us to just handle this
safety check in the DRM core though, since it's quite likely such an edge
case would break C drivers in addition to Rust drivers.
So, let's start enforcing this in drm_vblank_init by checking that every
CRTC has an enable_vblank function registered. Throw a warning if we find
that some CRTCs have it and others don't.
In the event that we don't actually find any CRTCs with vblank support,
simply skip init and return -ENODEV. We intentionally don't WARN_ON() this
scenario, as it isn't a fatal error and drivers which do support KMS but
don't end up registering any CRTCs can simply ignore the error. This is
also useful for Rust, since it saves us from having to track whether or not
any CRTCs registered vblank support ourselves.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
drivers/gpu/drm/drm_vblank.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
Comments
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] drm_vblank_init() causes a NULL pointer dereference or driver probe failure due to accessing uninitialized or empty crtc_list -- --- Patch [5]: [PATCH 5/5] drm/vblank: Require all CRTCs implement vblank support in drm_vblank_init() --- commit 178bbb448a16663eaad60425c62b446801e0f387 Author: Lyude Paul <lyude@redhat.com> drm/vblank: Require all CRTCs implement vblank support in drm_vblank_init() This commit modifies drm_vblank_init() to verify that all CRTCs implement vblank support, ensuring an all-or-nothing configuration. It returns -EINVAL if support is mixed, and -ENODEV if no CRTCs support vblank. > diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c > index d57405050554f..17affae23e7a6 100644 > --- a/drivers/gpu/drm/drm_vblank.c > +++ b/drivers/gpu/drm/drm_vblank.c > @@ -542,12 +542,31 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr) > * drmm_add_action_or_reset(). > * > * Returns: > - * Zero on success or a negative error code on failure. > + * Zero on success or a negative error code on failure. If no CRTCs with vblank > + * support implemented were found, -ENODEV will be returned. > */ > int drm_vblank_init(struct drm_device *dev) > { > int ret; > struct drm_crtc *crtc; > + bool found_vbl_crtc = false, found_non_vbl_crtc = false; > + > + /* Vblank hooks are per-CRTC, not per-device - which is contrary to how > + * the vblank core was written. Since hardware that only has vblank > + * support on some CRTCs but not all is non-existent and would likely > + * lead to UB, ensure that vblank support is all or nothing. > + */ > + drm_for_each_crtc(crtc, dev) { [Severity: High] Can iterating over dev->mode_config.crtc_list here cause a NULL pointer dereference or a false -ENODEV return during driver probe? Several DRM drivers call drm_vblank_init() before initializing mode_config or creating CRTCs. For example: In i915, intel_display_driver_probe_noirq() calls drm_vblank_init() before intel_mode_config_init() sets up the crtc_list, meaning the list head is uninitialized. In vkms, vkms_create() calls drm_vblank_init() before vkms_modeset_init() initializes the crtc_list. In zynqmp_kms, zynqmp_dpsub_drm_init() initializes the list but calls drm_vblank_init() before any CRTCs are created, meaning the list is empty and this function will unconditionally return -ENODEV. Does drm_vblank_init() need to support being called before CRTCs are registered? > + if (crtc->funcs->enable_vblank) > + found_vbl_crtc = true; > + else > + found_non_vbl_crtc = true; > + > + if (drm_WARN_ON(dev, found_vbl_crtc && found_non_vbl_crtc)) > + return -EINVAL; > + } > + if (!found_vbl_crtc) > + return -ENODEV;
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index d57405050554f..17affae23e7a6 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -542,12 +542,31 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr) * drmm_add_action_or_reset(). * * Returns: - * Zero on success or a negative error code on failure. + * Zero on success or a negative error code on failure. If no CRTCs with vblank + * support implemented were found, -ENODEV will be returned. */ int drm_vblank_init(struct drm_device *dev) { int ret; struct drm_crtc *crtc; + bool found_vbl_crtc = false, found_non_vbl_crtc = false; + + /* Vblank hooks are per-CRTC, not per-device - which is contrary to how + * the vblank core was written. Since hardware that only has vblank + * support on some CRTCs but not all is non-existent and would likely + * lead to UB, ensure that vblank support is all or nothing. + */ + drm_for_each_crtc(crtc, dev) { + if (crtc->funcs->enable_vblank) + found_vbl_crtc = true; + else + found_non_vbl_crtc = true; + + if (drm_WARN_ON(dev, found_vbl_crtc && found_non_vbl_crtc)) + return -EINVAL; + } + if (!found_vbl_crtc) + return -ENODEV; spin_lock_init(&dev->vbl_lock); spin_lock_init(&dev->vblank_time_lock);