All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Maxime Ripard" <mripard@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v6 26/28] drm/tidss: Implement readout support
Date: Thu, 15 Oct 2026 17:13:18 +0000	[thread overview]
Message-ID: <sashiko-outbox-173243@kernel.org> (raw)
In-Reply-To: <20261015-drm-state-readout-v6-26-6cc02cd10998@kernel.org>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [High] drm/tidss: uninitialized stack memory info leak in crtc readout
- [High] drm/tidss: integer overflow in calc_pixel_clock_hz() on 32-bit archs
- [High] drm/tidss: unhandled clock enable failure causes external abort crash
- [Medium] drm/tidss: memory leak of readout framebuffer on multi-crtc hardware
- [Medium] drm/tidss: permanent clock reference leak via double-enable in readout
- [Medium] drm/tidss: plane readout fails unconditionally on multi-crtc hardware
- [Medium] drm/tidss: clock enable count leak and underflow in CRTC readout/install
--

commit 5f7c5b078a348c064d70aaabd04294cf1916f772
Author: Maxime Ripard <mripard@kernel.org>

drm/tidss: Implement readout support

With the hardware readout infrastructure now in place in the KMS
framework, we can provide it for the tidss driver.

> diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c
> index 3da49f77fa080..666b950278ee4 100644
> --- a/drivers/gpu/drm/tidss/tidss_crtc.c
> +++ b/drivers/gpu/drm/tidss/tidss_crtc.c
[ ... ]
> @@ -370,6 +374,93 @@ static struct drm_crtc_state *tidss_crtc_create_state(struct drm_crtc *crtc)
>  	return &tstate->base;
>  }
>  
> +static int tidss_crtc_readout_state(struct drm_crtc *crtc,
> +				    struct drm_atomic_sro_state *state,
> +				    struct drm_crtc_state *crtc_state)
> +{
[ ... ]
> +	struct drm_display_mode mode;
> +	int ret;
> +

[Severity: High]
Can this uninitialized stack memory be leaked to userspace?

This struct is allocated on the stack without zero-initialization. When it is
passed to dispc_vp_readout_mode(), only some fields are populated, and the
flags field is modified using a bitwise OR, preserving the stack garbage. The
struct is then copied to the CRTC state via drm_atomic_set_mode_for_crtc(),
which can expose the uninitialized kernel stack memory directly to userspace.

> +	tidss_runtime_get(tidss);
> +
> +	if (!dispc_vp_is_enabled(dispc, tcrtc->hw_videoport))
> +		goto out;
> +
> +	/*
> +	 * The display is active, we need to enable our clock to have
> +	 * proper reference count.
> +	 */
> +	WARN_ON(dispc_vp_enable_clk(tidss->dispc, tcrtc->hw_videoport));

[Severity: High]
Does this unhandled clock enable failure cause a kernel panic on ARM platforms?

If dispc_vp_enable_clk() fails here, the code logs a warning but proceeds to
access the display controller's MMIO registers in dispc_vp_readout_mode(). On
ARM architectures, reading from an unclocked peripheral triggers a bus error
and an immediate external abort crash.

[Severity: Medium]
Can this clock enable cause an underflow in the reference count on error?

If this initial dispc_vp_enable_clk() fails, tidss_crtc_atomic_disable() will
later unconditionally call dispc_vp_disable_clk(), underflowing the clock
enable count. Additionally, if the clock enables successfully but a subsequent
error occurs during readout, there is no error cleanup to disable the clock.

> +
> +	tstate->base.active = 1;
> +	tstate->base.enable = 1;
[ ... ]
> +static void tidss_crtc_install_state(struct drm_crtc *crtc,
> +				     struct drm_crtc_state *crtc_state)
> +{
> +	struct tidss_crtc *tcrtc = to_tidss_crtc(crtc);
> +	struct drm_device *ddev = crtc->dev;
> +	struct tidss_device *tidss = to_tidss(ddev);
> +	int ret;
> +
> +	tidss_runtime_get(tidss);
> +
> +	ret = dispc_vp_enable_clk(tidss->dispc, tcrtc->hw_videoport);
> +	if (ret != 0)
> +		return;

[Severity: Medium]
Does this second clock enable cause a permanent reference count leak?

The video port clock was already enabled during tidss_crtc_readout_state().
Enabling it a second time here double-increments the reference count. Since
tidss_crtc_atomic_disable() only disables the clock once, this leaves a
permanent clock reference leak on the success path, preventing the hardware
from entering low-power states.

> +
> +	/* Turn vertical blanking interrupt reporting on. */
> +	drm_crtc_vblank_on(crtc);
> +}
[ ... ]
> diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c
> index fdd3b166c1181..50e6d9fb92083 100644
> --- a/drivers/gpu/drm/tidss/tidss_dispc.c
> +++ b/drivers/gpu/drm/tidss/tidss_dispc.c
[ ... ]
> +static unsigned long calc_pixel_clock_hz(unsigned int htotal,
> +					 unsigned int vtotal,
> +					 unsigned int refresh,
> +					 unsigned int freq_div)
> +{
> +	unsigned long rate = (unsigned long)htotal * vtotal * refresh;
> +
> +	return (rate * 1000) / freq_div;
> +}

[Severity: High]
Does this multiplication overflow on 32-bit architectures?

On 32-bit platforms (such as the ARM32 K2G SoCs supported by this driver),
rate uses 32-bit unsigned arithmetic. For a standard 1080p60 display, rate is
roughly 148,500,000. Multiplying this by 1000 yields 148,500,000,000, which
drastically exceeds the 32-bit maximum. This overflow results in a corrupted
clock frequency and breaks refresh rate calculations.

[ ... ]
> diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
> index b0d5d6959b885..32b80a3f8f7d3 100644
> --- a/drivers/gpu/drm/tidss/tidss_plane.c
> +++ b/drivers/gpu/drm/tidss/tidss_plane.c
[ ... ]
> +static struct drm_crtc *tidss_plane_readout_crtc(struct drm_plane *plane)
> +{
> +	struct drm_device *dev = plane->dev;
> +
> +	if (dev->num_crtcs != 1)
> +		return ERR_PTR(-EINVAL);

[Severity: Medium]
Will this intentionally break plane state readout on devices with multiple
video ports?

The hardware natively supports multiple CRTCs (e.g., AM65x has two video
ports), but this hardcoded check causes plane readout to fail unconditionally
on any multi-CRTC configuration. Hardware routing registers likely need to be
read to dynamically determine which CRTC the plane is connected to.

> +
> +	return list_first_entry(&dev->mode_config.crtc_list, struct drm_crtc, head);
> +}
> +
> +static int tidss_plane_atomic_readout_state(struct drm_plane *plane,
> +					    struct drm_atomic_sro_state *state,
> +					    struct drm_plane_state *plane_state)
> +{
[ ... ]
> +	fb = tidss_plane_readout_fb(plane);
> +	if (IS_ERR(fb)) {
> +		ret = PTR_ERR(fb);
> +		goto err_runtime_pm;
> +	}
> +
> +	crtc = tidss_plane_readout_crtc(plane);
> +	if (IS_ERR(crtc)) {
> +		ret = PTR_ERR(crtc);
> +		goto err_runtime_pm;
> +	}

[Severity: Medium]
Does this error path leak the dummy framebuffer?

tidss_plane_readout_fb() allocates and initializes fb with a reference count
of 1. If tidss_plane_readout_crtc() fails (which it does unconditionally on
multi-CRTC hardware), the code jumps to err_runtime_pm, bypassing the
assignment to plane_state->fb. Since drm_framebuffer_put() is never called,
the framebuffer memory and its IDR entry are permanently leaked.

> +
> +	plane_state->fb = fb;
> +	plane_state->crtc = crtc;
> +	plane_state->visible = true;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261015-drm-state-readout-v6-0-6cc02cd10998@kernel.org?part=26

  reply	other threads:[~2026-10-15 17:13 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 15:08 [PATCH v6 00/28] drm: Implement state readout support Maxime Ripard
2026-10-15 15:08 ` [PATCH v6 01/28] drm/atomic: Fix private obj error handling Maxime Ripard
2026-10-15 15:23   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 02/28] drm/atomic: Add drm_private_obj name Maxime Ripard
2026-10-15 15:23   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 03/28] drm/bridge: Switch print_state to use bridge name Maxime Ripard
2026-10-15 15:34   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 04/28] drm/bridge: Add drm_private_obj_is_bridge() Maxime Ripard
2026-10-15 15:28   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 05/28] drm/atomic: Export drm_atomic_*_print_state Maxime Ripard
2026-10-15 15:33   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 06/28] drm/atomic_sro: Create drm_atomic_sro_state container Maxime Ripard
2026-10-15 15:41   ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 07/28] drm/atomic_sro: Create kernel parameter to force or disable readout Maxime Ripard
2026-10-15 15:46   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 08/28] drm/atomic_sro: Add atomic state readout infrastructure Maxime Ripard
2026-10-15 15:52   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 09/28] drm/atomic_sro: Add function to install state into drm objects Maxime Ripard
2026-10-15 15:56   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 10/28] drm/atomic_sro: Create documentation Maxime Ripard
2026-10-15 15:59   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 11/28] drm/bridge: Handle bridges with hardware state readout Maxime Ripard
2026-10-15 16:05   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 12/28] drm/mode-config: Read out hardware state in drm_mode_config_create_state Maxime Ripard
2026-10-15 16:14   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 13/28] drm/atomic_sro: Provide helpers to implement hardware state readout Maxime Ripard
2026-10-15 16:21   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 14/28] drm/mode-config: Introduce hw_reset hook Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 15/28] drm/modeset-helper: Add drm_mode_config_helper_hw_reset() Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 16/28] drm/atomic_helper: Compare actual and readout states once the commit is done Maxime Ripard
2026-10-15 16:31   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 17/28] drm/atomic-state-helper: Provide comparison macros Maxime Ripard
2026-10-15 16:39   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 18/28] drm/atomic-state-helper: Provide atomic_compare_state helpers Maxime Ripard
2026-10-15 16:50   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 19/28] drm/atomic-helper: Document State Read-Out as a state initialization approach Maxime Ripard
2026-10-15 16:53   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 20/28] drm/encoder: Create atomic_sro_get_current_crtc hook Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 21/28] drm/bridge: display-connector: Implement readout support Maxime Ripard
2026-10-15 16:59   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 22/28] drm/bridge_connector: Implement hw readout for connector Maxime Ripard
2026-10-15 16:59   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 23/28] drm/tidss: crtc: Add atomic_print_state implementation Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 24/28] drm/tidss: dispc: Improve mode checking logs Maxime Ripard
2026-10-15 17:02   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 25/28] drm/tidss: Implement hw_reset Maxime Ripard
2026-10-15 17:09   ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 26/28] drm/tidss: Implement readout support Maxime Ripard
2026-10-15 17:13   ` sashiko-bot [this message]
2026-10-15 15:09 ` [PATCH v6 27/28] drm/tidss: encoder: Implement atomic_sro_get_current_crtc Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 28/28] drm/bridge: sii902x: Implement hw state readout Maxime Ripard
2026-10-15 17:20   ` sashiko-bot

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=sashiko-outbox-173243@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=mripard@kernel.org \
    --cc=sashiko-reviews@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.