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 v2 56/59] drm/nouveau: Convert to atomic_create_state
Date: Thu, 22 Oct 2026 12:55:53 +0000	[thread overview]
Message-ID: <sashiko-outbox-181514@kernel.org> (raw)
In-Reply-To: <20261022-drm-no-more-connector-reset-v2-56-0b7e4e85b1e8@kernel.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] drm/nouveau: invalid free via nouveau_conn_atomic_create_state() on pre-NV50
- [High] drm/nouveau: missing nvif teardown on error in nouveau_connector_create()
- [Medium] drm/nouveau: memory leak of mstc on error in nv50_mstc_new()
--

commit 37ea1f2bbde92fcd5731b31085bba035feef8a42
Author: Maxime Ripard <mripard@kernel.org>

drm/nouveau: Convert to atomic_create_state

This commit converts the nouveau connector implementation from using the
reset callback to using the atomic_create_state callback for initializing
connector state.

> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index e91130f93db67..947d0ff4ba029 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
[ ... ]
> @@ -1281,7 +1282,13 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
>  
>  	drm_connector_helper_add(&mstc->connector, &nv50_mstc_help);
>  
> -	mstc->connector.funcs->reset(&mstc->connector);
> +	conn_state = mstc->connector.funcs->atomic_create_state(&mstc->connector);
> +	if (IS_ERR(conn_state)) {
> +		drm_connector_cleanup(&mstc->connector);
> +		return PTR_ERR(conn_state);
> +	}

[Severity: Medium]
Earlier in nv50_mstc_new(), mstc and *pmstc are allocated with
kzalloc_obj(*mstc), and the error path for drm_connector_dynamic_init()
frees *pmstc and resets it to NULL:

	if (!(mstc = *pmstc = kzalloc_obj(*mstc)))
		return -ENOMEM;
	mstc->mstm = mstm;
	mstc->port = port;

	ret = drm_connector_dynamic_init(dev, &mstc->connector, &nv50_mstc,
					 DRM_MODE_CONNECTOR_DisplayPort, NULL);
	if (ret) {
		kfree(*pmstc);
		*pmstc = NULL;
		return ret;
	}

When atomic_create_state() fails here, drm_connector_cleanup() only cleans
up the embedded drm_connector and zeroes mstc->connector, while the caller
nv50_mstm_add_connector() discards mstc on a non-zero return.

Does this error path leak mstc and leave a dangling pointer in *pmstc?

> +	mstc->connector.state = conn_state;
> +
>  	nouveau_conn_attach_properties(&mstc->connector);
>  
>  	drm_for_each_crtc(crtc, dev) {
> diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
> index cc3caf8de64b0..e4ab9849de4d4 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_connector.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
> @@ -242,21 +242,17 @@ nouveau_conn_atomic_duplicate_state(struct drm_connector *connector)
>  	return &asyc->state;
>  }
>  
> -void
> -nouveau_conn_reset(struct drm_connector *connector)
> +struct drm_connector_state *
> +nouveau_conn_atomic_create_state(struct drm_connector *connector)
>  {
>  	struct nouveau_connector *nv_connector = nouveau_connector(connector);
>  	struct nouveau_conn_atom *asyc;
>  
>  	if (drm_drv_uses_atomic_modeset(connector->dev)) {
>  		if (WARN_ON(!(asyc = kzalloc_obj(*asyc))))
> -			return;
> +			return ERR_PTR(-ENOMEM);
>  
> -		if (connector->state)
> -			nouveau_conn_atomic_destroy_state(connector,
> -							  connector->state);
> -
> -		__drm_atomic_helper_connector_reset(connector, &asyc->state);
> +		__drm_atomic_helper_connector_state_init(&asyc->state, connector);
>  	} else {
>  		asyc = &nv_connector->properties_state;
>  	}
> @@ -278,6 +274,8 @@ nouveau_conn_reset(struct drm_connector *connector)
>  			break;
>  		}
>  	}
> +
> +	return &asyc->state;
>  }

[Severity: Critical]
On pre-nv50 display hardware (where disp->disp.object.oclass < NV50_DISP),
nv04_display_create() clears DRIVER_ATOMIC and uses
nouveau_mode_config_funcs without an atomic_commit callback, so
drm_drv_uses_atomic_modeset(connector->dev) is false.

Previously, nouveau_conn_reset() only called
__drm_atomic_helper_connector_reset() in the atomic branch, leaving
connector->state as NULL on pre-nv50 while initializing the embedded
nv_connector->properties_state in place.

With this change, nouveau_conn_atomic_create_state() returns
&nv_connector->properties_state.state, and nouveau_connector_create()
unconditionally assigns it to connector->state.

When nouveau_display_create() subsequently calls drm_mode_config_reset(),
drm_mode_config_connector_reset_with_create_state() sees the non-NULL
connector->state and passes it to nouveau_conn_atomic_destroy_state():

drivers/gpu/drm/nouveau/nouveau_connector.c:nouveau_conn_atomic_destroy_state() {
	struct nouveau_conn_atom *asyc = nouveau_conn_atom(state);
	__drm_atomic_helper_connector_destroy_state(&asyc->state);
	kfree(asyc);
}

The same destruction happens in drm_connector_cleanup(), and having
connector->state non-NULL on a non-atomic driver also causes helpers such
as drm_connector_get_encoder() to inspect connector->state->best_encoder
instead of connector->encoder.

Won't returning &nv_connector->properties_state.state and assigning it to
connector->state on pre-nv50 hardware pass an interior pointer of
struct nouveau_connector to kfree() and break legacy encoder lookups?

[ ... ]
> @@ -1521,7 +1520,13 @@ nouveau_connector_create(struct drm_device *dev, int index)
>  		}
>  	}
>  
> -	connector->funcs->reset(connector);
> +	conn_state = connector->funcs->atomic_create_state(connector);
> +	if (IS_ERR(conn_state)) {
> +		ret = PTR_ERR(conn_state);
> +		goto drm_conn_err;
> +	}

[Severity: High]
Before reaching atomic_create_state() in nouveau_connector_create(),
nv_connector->conn, nv_connector->hpd, and nv_connector->irq may already be
constructed via nvif_conn_ctor() and nvif_conn_event_ctor():

	if (nvif_object_constructed(&nv_connector->conn.object)) {
		ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug",
					   nouveau_connector_hotplug,
					   NVIF_CONN_EVENT_V0_PLUG | NVIF_CONN_EVENT_V0_UNPLUG,
					   &nv_connector->hpd);
		if (ret == 0)
			connector->polled = DRM_CONNECTOR_POLL_HPD;

		if (nv_connector->aux.transfer) {
			ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsDpIrq",
						   nouveau_connector_irq, NVIF_CONN_EVENT_V0_IRQ,
						   &nv_connector->irq);
			if (ret) {
				nvif_event_dtor(&nv_connector->hpd);
				nvif_conn_dtor(&nv_connector->conn);
				goto drm_conn_err;
			}
		}
	}

However, the drm_conn_err label only cleans up connector and frees
nv_connector:

drm_conn_err:
	drm_connector_cleanup(connector);
	kfree(nv_connector);
	return ERR_PTR(ret);

If atomic_create_state() fails and jumps to drm_conn_err without calling
nvif_event_dtor(&nv_connector->irq), nvif_event_dtor(&nv_connector->hpd),
and nvif_conn_dtor(&nv_connector->conn), can this leak those nvif objects
and leave active events referencing freed nv_connector memory?

> +	connector->state = conn_state;
> +
>  	nouveau_conn_attach_properties(connector);
>  
>  	/* Default scaling mode */
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261022-drm-no-more-connector-reset-v2-0-0b7e4e85b1e8@kernel.org?part=56

  reply	other threads:[~2026-10-22 12:56 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 12:30 [PATCH v2 00/59] drm/connector: Convert all drivers to atomic_create_state and remove reset Maxime Ripard
2026-10-22 12:30 ` Maxime Ripard
2026-10-22 12:30 ` Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 01/59] drm/hdmi: Change __drm_atomic_helper_connector_hdmi_state_init parameter order Maxime Ripard
2026-10-22 20:57   ` Maíra Canal
2026-10-22 12:31 ` [PATCH v2 02/59] drm/atomic-state-helper: Rename connector_tv_margins_reset to state_init Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 03/59] drm/atomic-state-helper: Rename connector_tv_reset " Maxime Ripard
2026-10-22 21:01   ` Maíra Canal
2026-10-22 12:31 ` [PATCH v2 04/59] drm/panel: Add atomic_create_state support Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 05/59] drm/amdgpu: vkms: Switch to drm_atomic_helper_connector_create_state Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 06/59] drm/aspeed: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 07/59] drm/ast: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 08/59] drm/bridge: analogix-anx6345: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 09/59] drm/bridge: analogix-anx78xx: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 10/59] drm/bridge: chrontel-ch7033: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 11/59] drm/bridge: nxp-ptn3460: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 12/59] drm/panel: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 13/59] drm/bridge: synopsys: dw-hdmi: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 14/59] drm/bridge: tc358767: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 15/59] drm/bridge: tda998x: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 16/59] drm/bridge: ti-tfp410: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 17/59] drm/exynos: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 18/59] drm/fsl-dcu: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 19/59] drm/hisilicon: hibmc: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 20/59] drm/logicvc: " Maxime Ripard
2026-10-25 10:24   ` Paul Kocialkowski
2026-10-22 12:31 ` [PATCH v2 21/59] drm/loongson: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 22/59] drm/mgag200: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 23/59] drm/mipi-dbi: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 24/59] drm/qxl: " Maxime Ripard
2026-10-22 12:42   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 25/59] drm/renesas: shmobile: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 26/59] drm/sitronix: st7571: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 27/59] drm/sitronix: st7920: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 28/59] drm/sti: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 29/59] drm/sun4i: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 30/59] drm/tegra: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 31/59] drm/tests: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 32/59] drm/tiny: arcpgu: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 33/59] drm/tiny: bochs: " Maxime Ripard
2026-10-22 12:42   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 34/59] drm/tiny: cirrus: " Maxime Ripard
2026-10-22 12:43   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 35/59] drm/tiny: gm12u320: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 36/59] drm/tiny: pixpaper: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 37/59] drm/tiny: repaper: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 38/59] drm/tiny: sharp: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 39/59] drm/udl: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 40/59] drm/vboxvideo: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 41/59] drm/virtio: " Maxime Ripard
2026-10-22 12:44   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 42/59] drm/vkms: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 43/59] drm/xen: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 44/59] drm/bridge: synopsys: dw-hdmi: Convert to atomic_create_state Maxime Ripard
2026-10-22 12:57   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 45/59] drm/meson: " Maxime Ripard
2026-10-22 12:31   ` Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 46/59] drm/gud: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 47/59] drm/sun4i: hdmi: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 48/59] drm/sun4i: tv: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 49/59] drm/tests: hdmi: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 50/59] drm/vc4: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 51/59] drm/vc4: vec: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 52/59] drm/connector: Remove drm_atomic_helper_connector_reset() Maxime Ripard
2026-10-22 12:50   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 53/59] drm/amdgpu: dm: Convert to atomic_create_state Maxime Ripard
2026-10-22 12:57   ` sashiko-bot
2026-10-22 16:17   ` Leo Li
2026-10-22 12:31 ` [PATCH v2 54/59] drm/ast: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 55/59] drm/i915: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 56/59] drm/nouveau: " Maxime Ripard
2026-10-22 12:31   ` Maxime Ripard
2026-10-22 12:55   ` sashiko-bot [this message]
2026-10-22 12:31 ` [PATCH v2 57/59] drm/tegra: " Maxime Ripard
2026-10-22 12:31 ` [PATCH v2 58/59] drm/connector: Remove __drm_atomic_helper_connector_reset() Maxime Ripard
2026-10-22 12:48   ` sashiko-bot
2026-10-22 12:31 ` [PATCH v2 59/59] drm/connector: Remove reset Maxime Ripard
2026-10-22 12:52   ` 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-181514@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.