Hi Henri

Sorry for the delay in replying.

On Fri, 3 Apr 2026 at 09:59, Henri Zikken <[email protected]> wrote:
>
> When a vc4 DRM device has no TXP (Writeback) CRTC, txp_crtc remains
> uninitialized after the drm_for_each_crtc loop. Subsequent calls to
> drm_crtc_mask(txp_crtc) then dereference a NULL pointer, causing a
> kernel panic.
>
> This was observed on Raspberry Pi Zero 2W with a DPI panel connected,
> where vc4_dpi_dev_probe triggers vc4_drm_bind which calls
> vc4_plane_create_additional_planes without a TXP being present.
>
> Fix by initializing txp_crtc to NULL and guarding all drm_crtc_mask()
> calls on txp_crtc with a NULL check.

Which tree have you created this patch against?

Creating a separate set of planes for the writeback connector is a
patch that I haven't upstreamed yet, so it only exists in our vendor
kernel[1].
This issue is already fixed on the rpi-6.18.y branch. It does exist on
earlier branches, but those are frozen for our ongoing development
efforts.

Then again if there is no transposer there is no point in creating the
additional planes at all. Creating them with a mask of 0 is a waste of
time.

  Dave

[1] https://github.com/raspberrypi/linux

> Fixes: (vc4_plane_create_additional_planes introduction)
> Signed-off-by: Henri Zikken<[email protected]>
> Signed-off-by: root <[email protected]>

Rogue Signed-off-by line.

> ---
>  drivers/gpu/drm/vc4/vc4_plane.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index fdd6ba310..c43c12c2c 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -2665,7 +2665,7 @@ int vc4_plane_create_additional_planes(struct 
> drm_device *drm)
>         struct drm_plane *cursor_plane;
>         struct drm_crtc *crtc;
>         unsigned int i;
> -       struct drm_crtc *txp_crtc;
> +       struct drm_crtc *txp_crtc = NULL;
>         uint32_t non_txp_crtc_mask;
>
>         drm_for_each_crtc(crtc, drm) {
> @@ -2678,7 +2678,7 @@ int vc4_plane_create_additional_planes(struct 
> drm_device *drm)
>         }
>
>         non_txp_crtc_mask = GENMASK(drm->mode_config.num_crtc - 1, 0) -
> -                                       drm_crtc_mask(txp_crtc);
> +                                       (txp_crtc ? drm_crtc_mask(txp_crtc) : 
> 0);
>
>         /* Set up some arbitrary number of planes.  We're not limited
>          * by a set number of physical registers, just the space in
> @@ -2707,7 +2707,7 @@ int vc4_plane_create_additional_planes(struct 
> drm_device *drm)
>         for (i = 0; i < VC4_NUM_TXP_OVERLAY_PLANES; i++) {
>                 struct drm_plane *plane =
>                         vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
> -                                      drm_crtc_mask(txp_crtc));
> +                                      (txp_crtc ? drm_crtc_mask(txp_crtc) : 
> 0));
>
>                 if (IS_ERR(plane))
>                         continue;
> --
> 2.39.5
>

Reply via email to