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

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] drm/amd/display: partial init and NULL deref when atomic_create_state() fails
- [Medium] drm/amd/display: ERR_PTR deref on cleanup in connector KUnit tests
--

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

drm/amdgpu: dm: Convert to atomic_create_state

This commit converts the amdgpu_dm connector state initialization from the
drm_connector_funcs.reset hook to drm_connector_funcs.atomic_create_state
across connectors, MST connectors, writeback connectors, and KUnit tests.

> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> index 3a4e98b08ac1f..e59595b5e39b2 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c

[ ... ]

> @@ -3199,8 +3195,16 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
>  	 * Some of the properties below require access to state, like bpc.
>  	 * Allocate some default initial connector state with our reset helper.
>  	 */
> -	if (aconnector->base.funcs->reset)
> -		aconnector->base.funcs->reset(&aconnector->base);
> +	if (!aconnector->base.state &&
> +	    aconnector->base.funcs->atomic_create_state) {
> +		struct drm_connector_state *conn_state;
> +
> +		conn_state = aconnector->base.funcs->atomic_create_state(&aconnector->base);
> +		if (IS_ERR(conn_state))
> +			return;
> +
> +		aconnector->base.state = conn_state;
> +	}
>  
>  	aconnector->connector_id = link_index;
>  	aconnector->bl_idx = -1;

[Severity: High]
What happens in the callers of amdgpu_dm_connector_init_helper() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c when
atomic_create_state() fails with ERR_PTR(-ENOMEM) and returns early?

Returning early from this void function skips initializing
aconnector->dc_link, aconnector->bl_idx = -1, aconnector->audio_inst = -1,
aconnector->hpd_lock, aconnector->handle_mst_msg_ready, and connector
properties, while leaving aconnector->base.state as NULL without reporting
an error to the caller.

In drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c,
amdgpu_dm_connector_init() continues execution assuming the connector was
initialized:

    amdgpu_dm_connector_init_helper(
        dm,
        aconnector,
        connector_type,
        link,
        link_index);
    ...
    if (dc_is_dp_signal(link->connector_signal))
        amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);

For DP or eDP connectors, amdgpu_dm_connector_init() ->
amdgpu_dm_initialize_dp_connector() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c immediately
dereferences aconnector->dc_link while it is still NULL:

    aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;

For other connectors, amdgpu_dm_mode_config_init() proceeds to call
amdgpu_dm_update_connector_after_detect(), which also dereferences
aconnector->dc_link->local_sink. In addition, if
amdgpu_dm_connector_destroy() runs on this partially initialized connector,
aconnector->bl_idx is still 0 rather than -1, so it will unregister
dm->backlight_dev[0].

Similarly, in drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c,
dm_dp_add_mst_connector() calls amdgpu_dm_connector_init_helper() and then
calls drm_connector_attach_max_bpc_property(connector, 8, 16), which
dereferences connector->state while it is NULL:

    amdgpu_dm_connector_init_helper(
        &adev->dm,
        aconnector,
        DRM_MODE_CONNECTOR_DisplayPort,
        master->dc_link,
        master->connector_id);
    ...
    connector->max_bpc_property = master->base.max_bpc_property;
    if (connector->max_bpc_property)
        drm_connector_attach_max_bpc_property(connector, 8, 16);

Along the same lines, in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c,
amdgpu_dm_wb_connector_init() ignores an ERR_PTR return from
amdgpu_dm_connector_atomic_create_state() and returns 0 with
connector->state left as NULL:

    conn_state = amdgpu_dm_connector_atomic_create_state(connector);
    if (!IS_ERR(conn_state)) {
        if (connector->state)
            connector->funcs->atomic_destroy_state(connector, connector->state);

        connector->state = conn_state;
    }

Should amdgpu_dm_connector_init_helper() and amdgpu_dm_wb_connector_init()
propagate the allocation error to their callers so connector initialization
can fail cleanly?

[ ... ]

> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
> index 8117aaf41f220..ebf8155326cb1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
> @@ -1468,19 +1468,19 @@ static void dm_test_decide_crtc_timing_no_crtc_clock(struct kunit *test)
>  	KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 0);
>  }
>  
> -/* Tests for amdgpu_dm_connector_funcs_reset() */
> +/* Tests for amdgpu_dm_connector_atomic_create_state() */
>  
>  static const struct drm_connector_funcs dm_test_connector_funcs = {
> -	.reset = amdgpu_dm_connector_funcs_reset,
> +	.atomic_create_state = amdgpu_dm_connector_atomic_create_state,
>  	.atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
>  };
>  
>  /**
> - * dm_test_funcs_reset_sets_defaults - Test funcs_reset sets defaults
> + * dm_test_atomic_create_sets_defaults - Test funcs_reset sets defaults
>   * @test: The KUnit test context
>   */
> -static void dm_test_funcs_reset_sets_defaults(struct kunit *test)
> +static void dm_test_atomic_create_sets_defaults(struct kunit *test)
>  {
>  	struct device *dev;
>  	struct drm_device *drm;
> @@ -1501,9 +1501,9 @@ static void dm_test_funcs_reset_sets_defaults(struct kunit *test)
>  	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
>  			    DRM_MODE_CONNECTOR_DisplayPort, NULL);
>  
> -	amdgpu_dm_connector_funcs_reset(connector);
> +	connector->state = amdgpu_dm_connector_atomic_create_state(connector);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector->state);
>  
> -	KUNIT_ASSERT_NOT_NULL(test, connector->state);
>  	dm_state = to_dm_connector_state(connector->state);
>  	KUNIT_EXPECT_EQ(test, (int)dm_state->scaling, (int)RMX_OFF);
>  	KUNIT_EXPECT_FALSE(test, dm_state->underscan_enable);
> @@ -1515,10 +1515,10 @@ static void dm_test_funcs_reset_sets_defaults(struct kunit *test)
>  }
>  
>  /**
> - * dm_test_funcs_reset_edp_abm_level - Test funcs_reset eDP sets ABM
> + * dm_test_atomic_create_edp_abm_level - Test funcs_reset eDP sets ABM
>   * @test: The KUnit test context
>   */
> -static void dm_test_funcs_reset_edp_abm_level(struct kunit *test)
> +static void dm_test_atomic_create_edp_abm_level(struct kunit *test)
>  {
>  	struct device *dev;
>  	struct drm_device *drm;
> @@ -1542,9 +1542,10 @@ static void dm_test_funcs_reset_edp_abm_level(struct kunit *test)
>  
>  	/* Test with abm_level > 0 */
>  	amdgpu_dm_set_abm_level_param(3);
> -	amdgpu_dm_connector_funcs_reset(connector);
>  
> -	KUNIT_ASSERT_NOT_NULL(test, connector->state);
> +	connector->state = amdgpu_dm_connector_atomic_create_state(connector);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector->state);
> +
>  	dm_state = to_dm_connector_state(connector->state);
>  	KUNIT_EXPECT_EQ(test, (int)dm_state->abm_level, 3);
>  
> @@ -1552,11 +1553,11 @@ static void dm_test_funcs_reset_edp_abm_level(struct kunit *test)
>  }
>  
>  /**
> - * dm_test_funcs_reset_edp_abm_disabled - Test funcs_reset eDP ABM
> + * dm_test_atomic_create_edp_abm_disabled - Test funcs_reset eDP ABM
>   * disabled
>   * @test: The KUnit test context
>   */
> -static void dm_test_funcs_reset_edp_abm_disabled(struct kunit *test)
> +static void dm_test_atomic_create_edp_abm_disabled(struct kunit *test)
>  {
>  	struct device *dev;
>  	struct drm_device *drm;
> @@ -1580,9 +1581,10 @@ static void dm_test_funcs_reset_edp_abm_disabled(struct kunit *test)
>  
>  	/* Test with abm_level <= 0 → immediate disable */
>  	amdgpu_dm_set_abm_level_param(-1);
> -	amdgpu_dm_connector_funcs_reset(connector);
>  
> -	KUNIT_ASSERT_NOT_NULL(test, connector->state);
> +	connector->state = amdgpu_dm_connector_atomic_create_state(connector);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector->state);
> +
>  	dm_state = to_dm_connector_state(connector->state);
>  	KUNIT_EXPECT_EQ(test, (int)dm_state->abm_level,
>  			(int)ABM_LEVEL_IMMEDIATE_DISABLE);
> @@ -1620,8 +1622,8 @@ static void dm_test_atomic_dup_state_copies_fields(struct kunit *test)
>  	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
>  			    DRM_MODE_CONNECTOR_HDMIA, NULL);
>  
> -	amdgpu_dm_connector_funcs_reset(connector);
> -	KUNIT_ASSERT_NOT_NULL(test, connector->state);
> +	connector->state = amdgpu_dm_connector_atomic_create_state(connector);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector->state);
>  
>  	/* Modify original state fields */
>  	dm_state = to_dm_connector_state(connector->state);

[Severity: Medium]
In dm_test_atomic_create_sets_defaults(),
dm_test_atomic_create_edp_abm_level(),
dm_test_atomic_create_edp_abm_disabled(), and
dm_test_atomic_dup_state_copies_fields() in
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c, can
assigning directly to connector->state before
KUNIT_ASSERT_NOT_ERR_OR_NULL() cause an error pointer dereference during
test teardown?

Each of these tests initializes the connector with drmm_connector_init(),
which registers drm_connector_cleanup() as a managed cleanup action. If
amdgpu_dm_connector_atomic_create_state() returns ERR_PTR(-ENOMEM),
connector->state holds that non-NULL error pointer when
KUNIT_ASSERT_NOT_ERR_OR_NULL() aborts the test, and drm_connector_cleanup()
in drivers/gpu/drm/drm_connector.c will then pass it to
atomic_destroy_state():

    if (connector->state && connector->funcs->atomic_destroy_state)
        connector->funcs->atomic_destroy_state(connector,
                               connector->state);

Would it be safer to store the return value in a local conn_state variable
and assert KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state) before assigning
connector->state, as done in the other tests in this file?

[ ... ]

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

  reply	other threads:[~2026-10-22 12:58 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 [this message]
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
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-181522@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.