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 [thread overview]
Message-ID: <20260814203542.1405135-6-lyude@redhat.com> (raw)
In-Reply-To: <20260814203542.1405135-1-lyude@redhat.com>
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(-)
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);
--
2.55.0
prev parent reply other threads:[~2026-08-14 20:38 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 20:35 [PATCH 0/5] drm/vblank: Enforce all-or-nothing vblank support Lyude Paul
2026-08-14 20:35 ` [PATCH 1/5] drm/vblank: Add drm_device.has_hw_vblank Lyude Paul
2026-08-14 20:35 ` [PATCH 2/5] drm/vblank: Remove drm->num_crtcs Lyude Paul
2026-08-14 20:35 ` [PATCH 3/5] drm/vblank: Remove num_crtcs argument from drm_vblank_init() Lyude Paul
2026-08-14 20:35 ` [PATCH 4/5] drm/vblank: Use drm_for_each_crtc() in drm_vblank_init() Lyude Paul
2026-08-14 20:35 ` Lyude Paul [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814203542.1405135-6-lyude@redhat.com \
--to=lyude@redhat.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=asahi@lists.linux.dev \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=imx@lists.linux.dev \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=linux-sunxi@lists.linux.dev \
--cc=linux-tegra@vger.kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=spice-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox