dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Andrei Rusu de Castro" <arc@empyreal.works>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 3/4] drm/amd/display: pass userspace brightness to power module
Date: Wed, 02 Sep 2026 12:57:22 +0000	[thread overview]
Message-ID: <20260902125722.8CC1A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260902-brightness-3-50f94618@empyreal.works>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Double application of PWM bitmask quirk and mathematical corruption on millinits.

Pre-existing issues:
- [High] Sleeping function called from atomic context.
- [High] Potential division by zero in brightness conversion functions when processing malformed firmware capabilities.
--

commit 5d73b2399ca1fd59d638eb586a83e6e63cc7a221
Author: Andrei Rusu de Castro <arc@empyreal.works>

drm/amd/display: pass userspace brightness to power module

The power module consumes millipercent and builds its own PWM lookup table
from the ATIF brightness transfer characteristics. This patch passes the
original userspace percentage to the power module on PWM panels and keeps
the existing nits conversion and source-unit brightness mask for AUX panels.
It also wires the brightness bypass to the power module's existing linear
bypass.

> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
> index 424b33573a734..04e810af4623c 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
> @@ -218,6 +218,41 @@ u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
>  }
>  EXPORT_IF_KUNIT(convert_brightness_to_user);

[Severity: High]
This isn't a bug introduced by this patch, but can
convert_brightness_to_user() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c trigger a
kernel panic via division by zero?

If a connected monitor's EDID/DPCD reports identical max_luminance and
min_luminance values:
amdgpu_dm_update_backlight_caps() will set
aux_max_input_signal == aux_min_input_signal.

This causes max - min == 0 to be returned by get_brightness_range().
Subsequently, calling amdgpu_dm_backlight_get_level() will execute
convert_brightness_to_user(), which evaluates
DIV_ROUND_CLOSEST_ULL(..., max - min), triggering a division by zero.

This could allow a Denial of Service attack against the host system by
plugging in an untrusted, maliciously crafted DisplayPort monitor or dock.

> +static u32 convert_brightness_to_millipercent(const struct amdgpu_dm_backlight_caps *caps,
> +					      u32 brightness)
[ ... ]
> +STATIC_IFN_KUNIT
> +u32 convert_brightness_for_power_module(const struct amdgpu_dm_backlight_caps *caps,
> +					u32 user_brightness)
> +{
> +	u32 brightness;
> +
> +	if (!caps)
> +		return user_brightness;
> +
> +	if (!caps->aux_support)
> +		return convert_brightness_to_millipercent(caps, user_brightness);
> +
> +	brightness = convert_brightness_from_user(caps, user_brightness);
> +	if (caps->brightness_mask)
> +		brightness |= caps->brightness_mask;

[Severity: High]
Does convert_brightness_for_power_module() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c erroneously
apply the hardware bitmask quirk to a mathematical millinits value prior to
handoff?

For AUX panels, caps->brightness_mask is OR'ed into the mathematically
scaled millinits brightness variable here. This corrupted value is then
passed to mod_power_set_backlight_nits(), which converts it to a PWM value.

> +
> +	return brightness;
> +}
> +
> +EXPORT_IF_KUNIT(convert_brightness_for_power_module);
> +
>  STATIC_IFN_KUNIT
>  struct dc_stream_state *dm_find_stream_with_link(
>  	struct amdgpu_display_manager *dm,
> @@ -262,7 +297,6 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
>  	bool rc = false, reallow_idle = false;
>  	struct drm_connector *connector;
>  	struct dc_stream_state *stream;

[Severity: High]
This isn't a bug introduced by this patch, but does
amdgpu_dm_backlight_set_level() in
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c safely handle
calling mutex_lock(&dm->dc_lock)?

amdgpu_dm_backlight_set_level() explicitly locks the mutex, but it is
reached via amdgpu_dm_atomic_commit_tail() during non-blocking display
atomic commits. Calling a sleeping function from atomic context can lead to
kernel warnings (lockdep splats), system instability, and potential
deadlocks.

>  
>  	list_for_each_entry(connector, &dm->ddev->mode_config.connector_list, head) {
>  		struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
[ ... ]
> diff --git a/drivers/gpu/drm/amd/display/modules/power/power_abm.c b/drivers/gpu/drm/amd/display/modules/power/power_abm.c
> index 5e86889eaa841..4d7d80ac60c9b 100644
> --- a/drivers/gpu/drm/amd/display/modules/power/power_abm.c
> +++ b/drivers/gpu/drm/amd/display/modules/power/power_abm.c
> @@ -1020,6 +1020,10 @@ void fill_backlight_level_params(struct core_power *core_power,
>  
>  	if (backlight_control_type == BACKLIGHT_CONTROL_AMD_AUX && !is_hdr)
>  		backlight_level_params->control_type = BACKLIGHT_CONTROL_PWM;
> +
> +	if (backlight_level_params->control_type == BACKLIGHT_CONTROL_PWM)
> +		backlight_level_params->backlight_pwm_u16_16 |=
> +			bl_prop->brightness_mask;

[Severity: High]
For non-HDR AUX panels falling back to PWM, does
fill_backlight_level_params() in
drivers/gpu/drm/amd/display/modules/power/power_abm.c apply the bitmask
a second time onto the resulting PWM value, leading to undefined hardware
behavior?

>  }
>  
>  bool mod_power_set_backlight_nits(struct mod_power *mod_power,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902-brightness-cover-abf809f2@empyreal.works?part=3

  reply	other threads:[~2026-09-02 12:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 12:31 [PATCH 0/4] drm/amd/display: fix brightness ownership through power module Andrei Rusu de Castro
2026-09-02 12:31 ` [PATCH 1/4] drm/amd/display: keep custom brightness curve in userspace domain Andrei Rusu de Castro
2026-09-02 12:31 ` [PATCH 2/4] drm/amd/display: test custom brightness with non-zero minimum Andrei Rusu de Castro
2026-09-02 12:32 ` [PATCH 3/4] drm/amd/display: pass userspace brightness to power module Andrei Rusu de Castro
2026-09-02 12:57   ` sashiko-bot [this message]
2026-09-02 12:33 ` [PATCH 4/4] drm/amd/display: test power module brightness input domain Andrei Rusu de Castro
2026-09-02 22:31 ` [PATCH v2 0/4] drm/amd/display: fix brightness ownership through power module Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 1/4] drm/amd/display: keep custom brightness curve in userspace domain Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 2/4] drm/amd/display: test custom brightness with non-zero minimum Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 3/4] drm/amd/display: pass userspace brightness to power module Andrei Rusu de Castro
2026-09-03  7:50     ` sashiko-bot
2026-09-02 22:32   ` [PATCH v2 4/4] drm/amd/display: test power module brightness input domain Andrei Rusu de Castro

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=20260902125722.8CC1A1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=arc@empyreal.works \
    --cc=dri-devel@lists.freedesktop.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).