Thank you for your contribution! Sashiko AI review found 4 potential issue(s) 
to consider:
- [Critical] Missing validation allows the CRTC to be enabled without a primary 
plane, causing a NULL pointer dereference in `arc_pgu_set_pxl_fmt()`.
- [Critical] The CRTC atomic_enable hook accesses arcpgu->plane.state directly 
without holding the plane's lock, allowing a concurrent plane update to cause a 
Use-After-Free.
- [High] Disabling the primary plane incorrectly clears the global CRTC enable 
bit, permanently desyncing hardware state from the DRM core.
- [High] Missing `.cleanup_fb` callback causes GEM object pin count leak on 
every plane update.
--

commit a8222dfe6a09a56b144901613fe5caafe6889898
Author: Davide Bonatto <[email protected]>

drm/tiny: arcpgu: Replace simple display pipe with regular atomic helpers
    
This commit migrates the arcpgu driver from the legacy drm_simple_display_pipe
infrastructure to explicitly managing plane, CRTC, and encoder objects using
standard atomic helpers.

> diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
> index c93d61ac0bb75..e500e6e52b669 100644
> --- a/drivers/gpu/drm/tiny/arcpgu.c
> +++ b/drivers/gpu/drm/tiny/arcpgu.c
[ ... ]
> @@ -117,8 +125,8 @@ static const u32 arc_pgu_supported_formats[] = {
>  
>  static void arc_pgu_set_pxl_fmt(struct arcpgu_drm_private *arcpgu)
>  {
> -     const struct drm_framebuffer *fb = arcpgu->pipe.plane.state->fb;
> -     uint32_t pixel_format = fb->format->format;
> +     const struct drm_framebuffer *fb = arcpgu->plane.state->fb;
> +     u32 pixel_format = fb->format->format;

[Severity: Critical]
What happens if userspace enables the CRTC but disables the primary plane?

In that scenario, fb would be NULL, and the subsequent fb->format->format
dereference would crash the kernel. The driver does not appear to have a
CRTC atomic_check hook to prevent enabling the CRTC without a valid plane,
and arc_pgu_plane_atomic_check() gracefully returns 0 when the framebuffer
is missing.

[Severity: Critical]
Can a concurrent plane update cause a use-after-free here?

This function is called from the CRTC enable path:
arc_pgu_crtc_atomic_enable() -> arc_pgu_mode_set() -> arc_pgu_set_pxl_fmt()

Since there is no CRTC atomic_check hook calling
drm_atomic_add_affected_planes(), a modeset only locks the CRTC and not
the plane. A concurrent plane update (page flip) could acquire the plane
lock, swap the state, and free the old framebuffer, causing the modesetting
thread to read freed memory when locklessly accessing fb->format->format.

[ ... ]
> +static void arc_pgu_plane_atomic_disable(struct drm_plane *plane,
> +                                      struct drm_atomic_commit *state)
> +{
> +     struct arcpgu_drm_private *arcpgu = plane_to_arcpgu(plane);
> +
> +     arc_pgu_write(arcpgu, ARCPGU_REG_BUF0_ADDR, 0);
> +     arc_pgu_write(arcpgu, ARCPGU_REG_CTRL,
> +                   arc_pgu_read(arcpgu, ARCPGU_REG_CTRL) &
> +                   ~ARCPGU_CTRL_ENABLE_MASK);
> +}

[Severity: High]
Does clearing ARCPGU_CTRL_ENABLE_MASK permanently desync the hardware state?

This appears to be the global CRTC enable bit. If userspace disables just
the primary plane, this clears the global enable bit for the entire CRTC.
When the plane is later re-enabled, arc_pgu_plane_atomic_update() sets the
buffer address but does not restore the CRTC enable bit, leaving the
display controller completely disabled and causing VBLANK timeouts.

[ ... ]
> +static const struct drm_plane_helper_funcs arc_pgu_plane_helper_funcs = {
> +     .atomic_update = arc_pgu_plane_atomic_update,
> +     .prepare_fb = drm_gem_plane_helper_prepare_fb,
> +     .atomic_check = arc_pgu_plane_atomic_check,
> +     .atomic_disable = arc_pgu_plane_atomic_disable,
> +};

[Severity: High]
Does this leak the GEM object pin count on every plane update?

The prepare_fb hook is set to drm_gem_plane_helper_prepare_fb, which pins
the backing BO for the framebuffer. However, there is no corresponding
cleanup_fb callback (drm_gem_plane_helper_cleanup_fb) to unpin it. 
Whenever a framebuffer is replaced during a page flip or disabled, its pin
count will never be decremented.

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to