Linux virtualization list
 help / color / mirror / Atom feed
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)



  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