Commit 0f15cbc2 authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher
Browse files

drm/amd: Sanity check the ACPI EDID



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: default avatarTobias Jakobi <tjakobi@math.uni-bielefeld.de>
Reported-and-tested-by: default avatarChris Bainbridge <chris.bainbridge@gmail.com>
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3782


Fixes: c6a83708 ("drm/amd/display: Fetch the EDID from _DDC if available for eDP")
Reviewed-by: default avatarHarry Wentland <harry.wentland@amd.com>
Link: https://lore.kernel.org/r/20241128032500.2088288-1-superm1@kernel.org


Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 68927514
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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: