On 2024-11-27 22:25, Mario Limonciello wrote: > From: Mario Limonciello <mario.limonciello@xxxxxxx> > > 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 <tjakobi@xxxxxxxxxxxxxxxxxxxxx> > Reported-and-tested-by: Chris Bainbridge <chris.bainbridge@xxxxxxxxx> > 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 <mario.limonciello@xxxxxxx> Reviewed-by: Harry Wentland <harry.wentland@xxxxxxx> 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: