]> Git Repo - J-linux.git/commitdiff
drm/amd: Sanity check the ACPI EDID
authorMario Limonciello <[email protected]>
Thu, 28 Nov 2024 03:25:00 +0000 (21:25 -0600)
committerAlex Deucher <[email protected]>
Mon, 2 Dec 2024 23:34:43 +0000 (18:34 -0500)
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")
Reviewed-by: Harry Wentland <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mario Limonciello <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c

index b0fea0856866d68b2e78a9f141effe2777ea26ee..6cbbb71d752beca0052c6e7db287df5a29c3e74e 100644 (file)
@@ -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:
This page took 0.047595 seconds and 4 git commands to generate.