On 2024-11-27 22:25, Mario Limonciello wrote:
> From: Mario Limonciello <[email protected]>
> 
> An HP Pavilion Aero Laptop 13-be0xxx/8916 has an ACPI EDID, but using
> it is causing corruption. It's got illogical values of not specifying
> a digital interface. Sanity check the ACPI EDID to avoid tripping such
> problems.
> 
> Suggested-by: Tobias Jakobi <[email protected]>
> Reported-and-tested-by: Chris Bainbridge <[email protected]>
> Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3782
> Fixes: c6a837088bed ("drm/amd/display: Fetch the EDID from _DDC if available 
> for eDP")
> Signed-off-by: Mario Limonciello <[email protected]>

Reviewed-by: Harry Wentland <[email protected]>

Harry

> ---
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c   | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index b0fea0856866d..6cbbb71d752be 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -907,14 +907,14 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, 
> unsigned int block, size_t len)
>       struct drm_connector *connector = data;
>       struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev);
>       unsigned char start = block * EDID_LENGTH;
> -     void *edid;
> +     struct edid *edid;
>       int r;
>  
>       if (!acpidev)
>               return -ENODEV;
>  
>       /* fetch the entire edid from BIOS */
> -     r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, &edid);
> +     r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, (void 
> *)&edid);
>       if (r < 0) {
>               drm_dbg(connector->dev, "Failed to get EDID from ACPI: %d\n", 
> r);
>               return r;
> @@ -924,7 +924,14 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, unsigned 
> int block, size_t len)
>               goto cleanup;
>       }
>  
> -     memcpy(buf, edid + start, len);
> +     /* sanity check */
> +     if (edid->revision < 4 || !(edid->input & DRM_EDID_INPUT_DIGITAL) ||
> +         (edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == 
> DRM_EDID_DIGITAL_TYPE_UNDEF) {
> +             r = -EINVAL;
> +             goto cleanup;
> +     }
> +
> +     memcpy(buf, (void *)edid + start, len);
>       r = 0;
>  
>  cleanup:

Reply via email to