On Sun, Oct 25, 2026 at 12:11 AM Atharva Tiwari
<[email protected]> wrote:
>
> From: Andre Eikmeyer <[email protected]>
>
> fwupd reads /dev/drm_dp_aux* while the GPU is runtime suspended. The AUX
> device holds no runtime PM reference, so the transfer touched registers of
> the powered off GPU and caused a CPU CATTER.
>
> Signed-off-by: Andre Eikmeyer <[email protected]>
> ---
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 7261317d4..b099bf520 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -24,6 +24,7 @@
>   *
>   */
>
> +#include <linux/pm_runtime.h>
>  #include <linux/vmalloc.h>
>  #include <drm/display/drm_dp_helper.h>
>  #include <drm/display/drm_dp_mst_helper.h>
> @@ -111,6 +112,20 @@ STATIC_IFN_KUNIT ssize_t dm_dp_aux_transfer(struct 
> drm_dp_aux *aux,
>         if (WARN_ON(msg->size > 16))
>                 return -E2BIG;
>
> +       ddc = TO_DM_AUX(aux)->ddc_service;
> +       adev = ddc->ctx->driver_context;
> +
> +       /*
> +        * User space reaches this through the drm_dp_aux_dev character device
> +        * without a runtime PM reference. Refuse the transfer while GMUX 
> keeps
> +        * the GPU powered off, a register access then hangs the PEG link.
> +        */
> +       pm_runtime_get_noresume(adev->dev);
> +       if (READ_ONCE(adev->gmux_off)) {

Nothing about this needs to be GMUX specific.

Alex

> +               pm_runtime_put_noidle(adev->dev);
> +               return -EBUSY;
> +       }
> +
>         payload.address = msg->address;
>         payload.data = msg->buffer;
>         payload.length = msg->size;
> @@ -126,13 +141,13 @@ STATIC_IFN_KUNIT ssize_t dm_dp_aux_transfer(struct 
> drm_dp_aux *aux,
>         result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, 
> &payload,
>                                       &operation_result);
>
> +       pm_runtime_put_autosuspend(adev->dev);
> +
>         /*
>          * w/a on certain intel platform where hpd is unexpected to pull low 
> during
>          * 1st sideband message transaction by return AUX_RET_ERROR_HPD_DISCON
>          * aux transaction is succuess in such case, therefore bypass the 
> error
>          */
> -       ddc = TO_DM_AUX(aux)->ddc_service;
> -       adev = ddc->ctx->driver_context;
>         if (adev->dm.aux_hpd_discon_quirk) {
>                 if (msg->address == DP_SIDEBAND_MSG_DOWN_REQ_BASE &&
>                         operation_result == AUX_RET_ERROR_HPD_DISCON) {
> --
> 2.55.0
>

Reply via email to