From: Thomas Zimmermann <tzimmermann@suse.de>
To: "Roman Ilin" <me@romanilin.is>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>
Cc: Louis Chauvet <louis.chauvet@bootlin.com>,
Javier Martinez Canillas <javierm@redhat.com>,
Dmitry Osipenko <dmitry.osipenko@collabora.com>,
dri-devel@lists.freedesktop.org, virtualization@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] drm/vblank: Don't arm vblank timer with invalid frame duration
Date: Tue, 30 Jun 2026 14:58:11 +0200 [thread overview]
Message-ID: <3e92dfd1-2979-4246-9aac-09e21ec43704@suse.de> (raw)
In-Reply-To: <20260613224434.96501-1-me@romanilin.is>
(cc Ville)
Hi,
thanks for addressing the issue.
Am 14.06.26 um 00:44 schrieb Roman Ilin:
> When a CRTC's display mode carries a too small pixel clock,
> drm_calc_timestamping_constants() computes a frame duration that
> exceeds INT_MAX. drm_vblank_crtc.framedur_ns becomes negative.
> drm_crtc_vblank_start_timer() then arms the vblank hrtimer with this
> interval, after which vblank events are no longer delivered. Pending
> page flips never complete and the display appears frozen.
>
> This could be triggered on virtio-gpu guests that have dynamic resolution
> enabled: when the SPICE agent or the X server resizes the output, it
> submits a mode whose pixel clock is off by a factor of 1000, e.g.:
'off by' as in it should be in Hz rather than kHz.
>
> clock = 406 kHz, htotal = 3152, vtotal = 2148
>
> framedur_ns = 3152 * 2148 * 1000000 / 406 = 16675852216 ns (~16.7 s)
>
> 16675852216 does not fit into an int and wraps to roughly -504000000.
> ns_to_ktime() then yields a negative interval and the timer stops working.
>
> Found by bisection, which pointed at commit a036f5fceedb ("drm/virtgpu:
> Use vblank timer"). That commit merely made virtio-gpu use the vblank
> timer and thereby exposed the pre-existing problem in the timer setup
> added by commit 74afeb812850 ("drm/vblank: Add vblank timer").
>
> Reject a non-positive frame duration in drm_crtc_vblank_start_timer() and
> return an error. enable_vblank then fails and the driver falls back to
> sending the vblank event immediately, as it did before the vblank timer
> was introduced. Valid modes are unaffected, and the timer self-heals on
> the next mode that has a sane clock.
>
> Fixes: 74afeb812850 ("drm/vblank: Add vblank timer")
> Cc: stable@vger.kernel.org
> Signed-off-by: Roman Ilin <me@romanilin.is>
> ---
> Notes:
>
> Based on v7.1-rc7. Tested on 6.19 and 7.1-rc7.
>
> Open questions:
>
> This relies on the int overflow producing a negative value. The deeper
> issue is that drm_calc_timestamping_constants() truncates framedur_ns to
> int. Would you prefer to widen framedur_ns to s64, or to bound the
> interval here (e.g. reject framedur_ns above one second) so that any
> bogus interval is rejected regardless of sign?
Generally speaking, I think we should not accept such a bugos mode in
the first place. But this would require changes to the mode-setting code
that are too invasive for a bug fix.
So, if anything, we should try to detect the problem in
drm_calc_timestamping_constants(). Let's make the helper return errno
codes instead of failing silently. Within the helper, let's do the
following changes:
- declare frame_size an unsigned int
- declare linedur_ns and framedur_ns of type u64
This should avoid possible overflows in the code. And before assigning
linedur_ns and framedur_ns to the vblank fields, test them against INT_MAX.
Maybe at [1]. Using drm_WARN_ON_ONCE is likely a good idea for future
debugging.
if (drm_WARN_ON_ONCE(dev, linedur_ns > INT_MAX) || drm_WARN_ON_ONCE(dev,
framedur_ns > INT_MAX))
return -EINVAL
[1]
https://elixir.bootlin.com/linux/v7.1.2/source/drivers/gpu/drm/drm_vblank.c#L662
>
> Should virtio-gpu additionally sanitize the user-supplied clock in its
> atomic_check (similar to vmwgfx for the clock==0 case) so the
> vblank-timer throttling is preserved for these resizes, instead of
> falling back to immediate events?
>
> drivers/gpu/drm/drm_vblank.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index f78bf37f1..557cd0bc8 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -2235,7 +2235,13 @@ int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
>
> drm_calc_timestamping_constants(crtc, &crtc->mode);
>
> + /*
> + * Return an error so the driver falls back to sending vblank events
> + * when a small mode clock yields a frame duration exceeding INT_MAX.
> + */
> + if (vblank->framedur_ns <= 0)
> + return -EINVAL;
Here, you would just forward the error upwards in the call stack.
Best regards
Thomas
> +
> spin_lock_irqsave(&vtimer->interval_lock, flags);
> vtimer->interval = ns_to_ktime(vblank->framedur_ns);
> spin_unlock_irqrestore(&vtimer->interval_lock, flags);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
next prev parent reply other threads:[~2026-06-30 12:58 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-13 22:44 [PATCH] drm/vblank: Don't arm vblank timer with invalid frame duration Roman Ilin
2026-06-30 12:06 ` Thorsten Leemhuis
2026-06-30 12:09 ` Thomas Zimmermann
2026-06-30 12:58 ` Thomas Zimmermann [this message]
2026-07-02 15:23 ` [PATCH v2] " Roman Ilin
2026-07-02 18:10 ` [PATCH v3] " Roman Ilin
2026-07-02 18:23 ` Roman Ilin
2026-07-03 7:26 ` Thomas Zimmermann
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=3e92dfd1-2979-4246-9aac-09e21ec43704@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@gmail.com \
--cc=dmitry.osipenko@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=javierm@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=louis.chauvet@bootlin.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=me@romanilin.is \
--cc=mripard@kernel.org \
--cc=simona@ffwll.ch \
--cc=ville.syrjala@linux.intel.com \
--cc=virtualization@lists.linux.dev \
/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