All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] drm/edid: cleanup and refactoring around validity checks
@ 2022-03-29 18:42 ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Emil Velikov

Another day, another batch of EDID code refactoring.

Mostly the goal was to simplify drm_do_get_edid(), but trying to extract
a const function for checking a single block validity lead me down a
rabbit hole...

BR,
Jani.


Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Emil Velikov <emil.l.velikov@gmail.com>

Jani Nikula (12):
  drm/edid: use struct edid * in drm_do_get_edid()
  drm/edid: clean up EDID block checksum functions
  drm/edid: add edid_block_tag() helper to get the EDID extension tag
  drm/edid: make drm_edid_header_is_valid() accept void pointer
  drm/edid: clean up edid_is_zero()
  drm/edid: split out edid_header_fix()
  drm/edid: split drm_edid_block_valid() to check and act parts
  drm/edid: use a better variable name for EDID block read retries
  drm/edid: simplify block check when filtering invalid blocks
  drm/edid: split out invalid block filtering to a separate function
  drm/edid: track invalid blocks in drm_do_get_edid()
  drm/edid: reduce magic when updating the EDID block checksum

 drivers/gpu/drm/drm_edid.c | 293 +++++++++++++++++++++----------------
 include/drm/drm_edid.h     |   2 +-
 2 files changed, 171 insertions(+), 124 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 00/12] drm/edid: cleanup and refactoring around validity checks
@ 2022-03-29 18:42 ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Another day, another batch of EDID code refactoring.

Mostly the goal was to simplify drm_do_get_edid(), but trying to extract
a const function for checking a single block validity lead me down a
rabbit hole...

BR,
Jani.


Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Emil Velikov <emil.l.velikov@gmail.com>

Jani Nikula (12):
  drm/edid: use struct edid * in drm_do_get_edid()
  drm/edid: clean up EDID block checksum functions
  drm/edid: add edid_block_tag() helper to get the EDID extension tag
  drm/edid: make drm_edid_header_is_valid() accept void pointer
  drm/edid: clean up edid_is_zero()
  drm/edid: split out edid_header_fix()
  drm/edid: split drm_edid_block_valid() to check and act parts
  drm/edid: use a better variable name for EDID block read retries
  drm/edid: simplify block check when filtering invalid blocks
  drm/edid: split out invalid block filtering to a separate function
  drm/edid: track invalid blocks in drm_do_get_edid()
  drm/edid: reduce magic when updating the EDID block checksum

 drivers/gpu/drm/drm_edid.c | 293 +++++++++++++++++++++----------------
 include/drm/drm_edid.h     |   2 +-
 2 files changed, 171 insertions(+), 124 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Mixing u8 * and struct edid * is confusing, switch to the latter.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d79b06f7f34c..0650b9217aa2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	void *data)
 {
 	int i, j = 0, valid_extensions = 0;
-	u8 *edid, *new;
-	struct edid *override;
+	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
 	if (override)
 		return override;
 
-	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
+	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
 	if (!edid)
 		return NULL;
 
 	/* if there's no extensions or no connector, we're done */
-	valid_extensions = edid[0x7e];
+	valid_extensions = edid->extensions;
 	if (valid_extensions == 0)
-		return (struct edid *)edid;
+		return edid;
 
 	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
 	if (!new)
 		goto out;
 	edid = new;
 
-	for (j = 1; j <= edid[0x7e]; j++) {
-		u8 *block = edid + j * EDID_LENGTH;
+	for (j = 1; j <= edid->extensions; j++) {
+		void *block = edid + j;
 
 		for (i = 0; i < 4; i++) {
 			if (get_edid_block(data, block, j, EDID_LENGTH))
@@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			valid_extensions--;
 	}
 
-	if (valid_extensions != edid[0x7e]) {
-		u8 *base;
+	if (valid_extensions != edid->extensions) {
+		struct edid *base;
 
-		connector_bad_edid(connector, edid, edid[0x7e] + 1);
+		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
-		edid[0x7e] = valid_extensions;
+		edid->checksum += edid->extensions - valid_extensions;
+		edid->extensions = valid_extensions;
 
 		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
 				    GFP_KERNEL);
@@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			goto out;
 
 		base = new;
-		for (i = 0; i <= edid[0x7e]; i++) {
-			u8 *block = edid + i * EDID_LENGTH;
+		for (i = 0; i <= edid->extensions; i++) {
+			void *block = edid + i;
 
 			if (!drm_edid_block_valid(block, i, false, NULL))
 				continue;
 
 			memcpy(base, block, EDID_LENGTH);
-			base += EDID_LENGTH;
+			base++;
 		}
 
 		kfree(edid);
 		edid = new;
 	}
 
-	return (struct edid *)edid;
+	return edid;
 
 out:
 	kfree(edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Mixing u8 * and struct edid * is confusing, switch to the latter.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d79b06f7f34c..0650b9217aa2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	void *data)
 {
 	int i, j = 0, valid_extensions = 0;
-	u8 *edid, *new;
-	struct edid *override;
+	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
 	if (override)
 		return override;
 
-	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
+	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
 	if (!edid)
 		return NULL;
 
 	/* if there's no extensions or no connector, we're done */
-	valid_extensions = edid[0x7e];
+	valid_extensions = edid->extensions;
 	if (valid_extensions == 0)
-		return (struct edid *)edid;
+		return edid;
 
 	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
 	if (!new)
 		goto out;
 	edid = new;
 
-	for (j = 1; j <= edid[0x7e]; j++) {
-		u8 *block = edid + j * EDID_LENGTH;
+	for (j = 1; j <= edid->extensions; j++) {
+		void *block = edid + j;
 
 		for (i = 0; i < 4; i++) {
 			if (get_edid_block(data, block, j, EDID_LENGTH))
@@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			valid_extensions--;
 	}
 
-	if (valid_extensions != edid[0x7e]) {
-		u8 *base;
+	if (valid_extensions != edid->extensions) {
+		struct edid *base;
 
-		connector_bad_edid(connector, edid, edid[0x7e] + 1);
+		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
-		edid[0x7e] = valid_extensions;
+		edid->checksum += edid->extensions - valid_extensions;
+		edid->extensions = valid_extensions;
 
 		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
 				    GFP_KERNEL);
@@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			goto out;
 
 		base = new;
-		for (i = 0; i <= edid[0x7e]; i++) {
-			u8 *block = edid + i * EDID_LENGTH;
+		for (i = 0; i <= edid->extensions; i++) {
+			void *block = edid + i;
 
 			if (!drm_edid_block_valid(block, i, false, NULL))
 				continue;
 
 			memcpy(base, block, EDID_LENGTH);
-			base += EDID_LENGTH;
+			base++;
 		}
 
 		kfree(edid);
 		edid = new;
 	}
 
-	return (struct edid *)edid;
+	return edid;
 
 out:
 	kfree(edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 02/12] drm/edid: clean up EDID block checksum functions
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Have two clear functions, one to compute the checksum over the EDID, and
another to get the checksum from the EDID. Throw away the diff function.

Ditch the drm_ prefix for static functions, and accept const void * to
help transition to struct edid * usage.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0650b9217aa2..73f05e0363c0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1597,25 +1597,25 @@ module_param_named(edid_fixup, edid_fixup, int, 0400);
 MODULE_PARM_DESC(edid_fixup,
 		 "Minimum number of valid EDID header bytes (0-8, default 6)");
 
-static int drm_edid_block_checksum(const u8 *raw_edid)
+static int edid_block_compute_checksum(const void *_block)
 {
+	const u8 *block = _block;
 	int i;
 	u8 csum = 0, crc = 0;
 
 	for (i = 0; i < EDID_LENGTH - 1; i++)
-		csum += raw_edid[i];
+		csum += block[i];
 
 	crc = 0x100 - csum;
 
 	return crc;
 }
 
-static bool drm_edid_block_checksum_diff(const u8 *raw_edid, u8 real_checksum)
+static int edid_block_get_checksum(const void *_block)
 {
-	if (raw_edid[EDID_LENGTH - 1] != real_checksum)
-		return true;
-	else
-		return false;
+	const struct edid *block = _block;
+
+	return block->checksum;
 }
 
 static bool drm_edid_is_zero(const u8 *in_edid, int length)
@@ -1704,8 +1704,8 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 		}
 	}
 
-	csum = drm_edid_block_checksum(raw_edid);
-	if (drm_edid_block_checksum_diff(raw_edid, csum)) {
+	csum = edid_block_compute_checksum(raw_edid);
+	if (csum != edid_block_get_checksum(raw_edid)) {
 		if (edid_corrupt)
 			*edid_corrupt = true;
 
@@ -1859,7 +1859,7 @@ static void connector_bad_edid(struct drm_connector *connector,
 	/* Calculate real checksum for the last edid extension block data */
 	if (last_block < num_blocks)
 		connector->real_edid_checksum =
-			drm_edid_block_checksum(edid + last_block * EDID_LENGTH);
+			edid_block_compute_checksum(edid + last_block * EDID_LENGTH);
 
 	if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
 		return;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 02/12] drm/edid: clean up EDID block checksum functions
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Have two clear functions, one to compute the checksum over the EDID, and
another to get the checksum from the EDID. Throw away the diff function.

Ditch the drm_ prefix for static functions, and accept const void * to
help transition to struct edid * usage.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0650b9217aa2..73f05e0363c0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1597,25 +1597,25 @@ module_param_named(edid_fixup, edid_fixup, int, 0400);
 MODULE_PARM_DESC(edid_fixup,
 		 "Minimum number of valid EDID header bytes (0-8, default 6)");
 
-static int drm_edid_block_checksum(const u8 *raw_edid)
+static int edid_block_compute_checksum(const void *_block)
 {
+	const u8 *block = _block;
 	int i;
 	u8 csum = 0, crc = 0;
 
 	for (i = 0; i < EDID_LENGTH - 1; i++)
-		csum += raw_edid[i];
+		csum += block[i];
 
 	crc = 0x100 - csum;
 
 	return crc;
 }
 
-static bool drm_edid_block_checksum_diff(const u8 *raw_edid, u8 real_checksum)
+static int edid_block_get_checksum(const void *_block)
 {
-	if (raw_edid[EDID_LENGTH - 1] != real_checksum)
-		return true;
-	else
-		return false;
+	const struct edid *block = _block;
+
+	return block->checksum;
 }
 
 static bool drm_edid_is_zero(const u8 *in_edid, int length)
@@ -1704,8 +1704,8 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 		}
 	}
 
-	csum = drm_edid_block_checksum(raw_edid);
-	if (drm_edid_block_checksum_diff(raw_edid, csum)) {
+	csum = edid_block_compute_checksum(raw_edid);
+	if (csum != edid_block_get_checksum(raw_edid)) {
 		if (edid_corrupt)
 			*edid_corrupt = true;
 
@@ -1859,7 +1859,7 @@ static void connector_bad_edid(struct drm_connector *connector,
 	/* Calculate real checksum for the last edid extension block data */
 	if (last_block < num_blocks)
 		connector->real_edid_checksum =
-			drm_edid_block_checksum(edid + last_block * EDID_LENGTH);
+			edid_block_compute_checksum(edid + last_block * EDID_LENGTH);
 
 	if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
 		return;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 03/12] drm/edid: add edid_block_tag() helper to get the EDID extension tag
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The extension tag at offset 0 is not present in struct edid, add a
helper for it to reduce the need to use u8 *.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 73f05e0363c0..95f0303bc63e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1618,6 +1618,13 @@ static int edid_block_get_checksum(const void *_block)
 	return block->checksum;
 }
 
+static int edid_block_tag(const void *_block)
+{
+	const u8 *block = _block;
+
+	return block[0];
+}
+
 static bool drm_edid_is_zero(const u8 *in_edid, int length)
 {
 	if (memchr_inv(in_edid, 0, length))
@@ -1710,7 +1717,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			*edid_corrupt = true;
 
 		/* allow CEA to slide through, switches mangle this */
-		if (raw_edid[0] == CEA_EXT) {
+		if (edid_block_tag(raw_edid) == CEA_EXT) {
 			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
 			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
 		} else {
@@ -1722,7 +1729,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 	}
 
 	/* per-block-type checks */
-	switch (raw_edid[0]) {
+	switch (edid_block_tag(raw_edid)) {
 	case 0: /* base */
 		if (edid->version != 1) {
 			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
@@ -3366,7 +3373,7 @@ const u8 *drm_find_edid_extension(const struct edid *edid,
 	/* Find CEA extension */
 	for (i = *ext_index; i < edid->extensions; i++) {
 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
-		if (edid_ext[0] == ext_id)
+		if (edid_block_tag(edid_ext) == ext_id)
 			break;
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 03/12] drm/edid: add edid_block_tag() helper to get the EDID extension tag
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The extension tag at offset 0 is not present in struct edid, add a
helper for it to reduce the need to use u8 *.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 73f05e0363c0..95f0303bc63e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1618,6 +1618,13 @@ static int edid_block_get_checksum(const void *_block)
 	return block->checksum;
 }
 
+static int edid_block_tag(const void *_block)
+{
+	const u8 *block = _block;
+
+	return block[0];
+}
+
 static bool drm_edid_is_zero(const u8 *in_edid, int length)
 {
 	if (memchr_inv(in_edid, 0, length))
@@ -1710,7 +1717,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			*edid_corrupt = true;
 
 		/* allow CEA to slide through, switches mangle this */
-		if (raw_edid[0] == CEA_EXT) {
+		if (edid_block_tag(raw_edid) == CEA_EXT) {
 			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
 			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
 		} else {
@@ -1722,7 +1729,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 	}
 
 	/* per-block-type checks */
-	switch (raw_edid[0]) {
+	switch (edid_block_tag(raw_edid)) {
 	case 0: /* base */
 		if (edid->version != 1) {
 			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
@@ -3366,7 +3373,7 @@ const u8 *drm_find_edid_extension(const struct edid *edid,
 	/* Find CEA extension */
 	for (i = *ext_index; i < edid->extensions; i++) {
 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
-		if (edid_ext[0] == ext_id)
+		if (edid_block_tag(edid_ext) == ext_id)
 			break;
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 04/12] drm/edid: make drm_edid_header_is_valid() accept void pointer
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

It will be useful to accept a struct edid *, but for compatibility with
existing usage accept void *.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 8 +++++---
 include/drm/drm_edid.h     | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 95f0303bc63e..b5b21b50e476 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1580,13 +1580,15 @@ static const u8 edid_header[] = {
  *
  * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
  */
-int drm_edid_header_is_valid(const u8 *raw_edid)
+int drm_edid_header_is_valid(const void *_edid)
 {
+	const struct edid *edid = _edid;
 	int i, score = 0;
 
-	for (i = 0; i < sizeof(edid_header); i++)
-		if (raw_edid[i] == edid_header[i])
+	for (i = 0; i < sizeof(edid_header); i++) {
+		if (edid->header[i] == edid_header[i])
 			score++;
+	}
 
 	return score;
 }
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 48b1bf9c315a..b7e170584000 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -578,7 +578,7 @@ int drm_add_modes_noedid(struct drm_connector *connector,
 void drm_set_preferred_mode(struct drm_connector *connector,
 			    int hpref, int vpref);
 
-int drm_edid_header_is_valid(const u8 *raw_edid);
+int drm_edid_header_is_valid(const void *edid);
 bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			  bool *edid_corrupt);
 bool drm_edid_is_valid(struct edid *edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 04/12] drm/edid: make drm_edid_header_is_valid() accept void pointer
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

It will be useful to accept a struct edid *, but for compatibility with
existing usage accept void *.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 8 +++++---
 include/drm/drm_edid.h     | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 95f0303bc63e..b5b21b50e476 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1580,13 +1580,15 @@ static const u8 edid_header[] = {
  *
  * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
  */
-int drm_edid_header_is_valid(const u8 *raw_edid)
+int drm_edid_header_is_valid(const void *_edid)
 {
+	const struct edid *edid = _edid;
 	int i, score = 0;
 
-	for (i = 0; i < sizeof(edid_header); i++)
-		if (raw_edid[i] == edid_header[i])
+	for (i = 0; i < sizeof(edid_header); i++) {
+		if (edid->header[i] == edid_header[i])
 			score++;
+	}
 
 	return score;
 }
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 48b1bf9c315a..b7e170584000 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -578,7 +578,7 @@ int drm_add_modes_noedid(struct drm_connector *connector,
 void drm_set_preferred_mode(struct drm_connector *connector,
 			    int hpref, int vpref);
 
-int drm_edid_header_is_valid(const u8 *raw_edid);
+int drm_edid_header_is_valid(const void *edid);
 bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			  bool *edid_corrupt);
 bool drm_edid_is_valid(struct edid *edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 05/12] drm/edid: clean up edid_is_zero()
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Simplify, rename, take void pointer. No need for the drm_ prefix for
internal helpers.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b5b21b50e476..422db8ae0ac1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1627,12 +1627,9 @@ static int edid_block_tag(const void *_block)
 	return block[0];
 }
 
-static bool drm_edid_is_zero(const u8 *in_edid, int length)
+static bool edid_is_zero(const void *edid, int length)
 {
-	if (memchr_inv(in_edid, 0, length))
-		return false;
-
-	return true;
+	return !memchr_inv(edid, 0, length);
 }
 
 /**
@@ -1750,7 +1747,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 
 bad:
 	if (print_bad_edid) {
-		if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
+		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
 			pr_notice("EDID block is all zeroes\n");
 		} else {
 			pr_notice("Raw EDID:\n");
@@ -1878,7 +1875,7 @@ static void connector_bad_edid(struct drm_connector *connector,
 		u8 *block = edid + i * EDID_LENGTH;
 		char prefix[20];
 
-		if (drm_edid_is_zero(block, EDID_LENGTH))
+		if (edid_is_zero(block, EDID_LENGTH))
 			sprintf(prefix, "\t[%02x] ZERO ", i);
 		else if (!drm_edid_block_valid(block, i, false, NULL))
 			sprintf(prefix, "\t[%02x] BAD  ", i);
@@ -1955,7 +1952,7 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
 			goto out;
 		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
 			break;
-		if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
+		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
 			if (null_edid_counter)
 				(*null_edid_counter)++;
 			goto carp;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 05/12] drm/edid: clean up edid_is_zero()
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Simplify, rename, take void pointer. No need for the drm_ prefix for
internal helpers.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b5b21b50e476..422db8ae0ac1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1627,12 +1627,9 @@ static int edid_block_tag(const void *_block)
 	return block[0];
 }
 
-static bool drm_edid_is_zero(const u8 *in_edid, int length)
+static bool edid_is_zero(const void *edid, int length)
 {
-	if (memchr_inv(in_edid, 0, length))
-		return false;
-
-	return true;
+	return !memchr_inv(edid, 0, length);
 }
 
 /**
@@ -1750,7 +1747,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 
 bad:
 	if (print_bad_edid) {
-		if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
+		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
 			pr_notice("EDID block is all zeroes\n");
 		} else {
 			pr_notice("Raw EDID:\n");
@@ -1878,7 +1875,7 @@ static void connector_bad_edid(struct drm_connector *connector,
 		u8 *block = edid + i * EDID_LENGTH;
 		char prefix[20];
 
-		if (drm_edid_is_zero(block, EDID_LENGTH))
+		if (edid_is_zero(block, EDID_LENGTH))
 			sprintf(prefix, "\t[%02x] ZERO ", i);
 		else if (!drm_edid_block_valid(block, i, false, NULL))
 			sprintf(prefix, "\t[%02x] BAD  ", i);
@@ -1955,7 +1952,7 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
 			goto out;
 		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
 			break;
-		if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
+		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
 			if (null_edid_counter)
 				(*null_edid_counter)++;
 			goto carp;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 06/12] drm/edid: split out edid_header_fix()
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Give a name to the EDID header fixup instead of having an inline memcpy.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 422db8ae0ac1..481643751d10 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1572,6 +1572,11 @@ static const u8 edid_header[] = {
 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
 };
 
+static void edid_header_fix(void *edid)
+{
+	memcpy(edid, edid_header, sizeof(edid_header));
+}
+
 /**
  * drm_edid_header_is_valid - sanity check the header of the base EDID block
  * @raw_edid: pointer to raw base EDID block
@@ -1702,7 +1707,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			if (edid_corrupt)
 				*edid_corrupt = true;
 			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
-			memcpy(raw_edid, edid_header, sizeof(edid_header));
+			edid_header_fix(raw_edid);
 		} else {
 			if (edid_corrupt)
 				*edid_corrupt = true;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 06/12] drm/edid: split out edid_header_fix()
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Give a name to the EDID header fixup instead of having an inline memcpy.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 422db8ae0ac1..481643751d10 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1572,6 +1572,11 @@ static const u8 edid_header[] = {
 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
 };
 
+static void edid_header_fix(void *edid)
+{
+	memcpy(edid, edid_header, sizeof(edid_header));
+}
+
 /**
  * drm_edid_header_is_valid - sanity check the header of the base EDID block
  * @raw_edid: pointer to raw base EDID block
@@ -1702,7 +1707,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
 			if (edid_corrupt)
 				*edid_corrupt = true;
 			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
-			memcpy(raw_edid, edid_header, sizeof(edid_header));
+			edid_header_fix(raw_edid);
 		} else {
 			if (edid_corrupt)
 				*edid_corrupt = true;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add edid_block_check() that only checks the EDID block validity, without
any actions. Turns out it's simple and crystal clear.

Rewrite drm_edid_block_valid() around it, keeping all the functionality
fairly closely the same, warts and all. Turns out it's incredibly
complicated for a function you'd expect to be simple, with all the
fixing and printing and special casing. (Maybe we'll want to simplify it
in the future.)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
 1 file changed, 88 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 481643751d10..04eb6949c9c8 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
 }
 EXPORT_SYMBOL(drm_edid_are_equal);
 
+enum edid_block_status {
+	EDID_BLOCK_OK = 0,
+	EDID_BLOCK_NULL,
+	EDID_BLOCK_HEADER_CORRUPT,
+	EDID_BLOCK_HEADER_REPAIR,
+	EDID_BLOCK_HEADER_FIXED,
+	EDID_BLOCK_CHECKSUM,
+	EDID_BLOCK_VERSION,
+};
+
+static enum edid_block_status edid_block_check(const void *_block, bool base)
+{
+	const struct edid *block = _block;
+
+	if (!block)
+		return EDID_BLOCK_NULL;
+
+	if (base) {
+		int score = drm_edid_header_is_valid(block);
+
+		if (score < clamp(edid_fixup, 6, 8))
+			return EDID_BLOCK_HEADER_CORRUPT;
+
+		if (score < 8)
+			return EDID_BLOCK_HEADER_REPAIR;
+	}
+
+	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
+		return EDID_BLOCK_CHECKSUM;
+
+	if (base) {
+		if (block->version != 1)
+			return EDID_BLOCK_VERSION;
+	}
+
+	return EDID_BLOCK_OK;
+}
+
+static bool edid_block_status_valid(enum edid_block_status status, int tag)
+{
+	return status == EDID_BLOCK_OK ||
+		status == EDID_BLOCK_HEADER_FIXED ||
+		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
+}
+
 /**
  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
  * @raw_edid: pointer to raw EDID block
- * @block: type of block to validate (0 for base, extension otherwise)
+ * @block_num: type of block to validate (0 for base, extension otherwise)
  * @print_bad_edid: if true, dump bad EDID blocks to the console
  * @edid_corrupt: if true, the header or checksum is invalid
  *
@@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
  *
  * Return: True if the block is valid, false otherwise.
  */
-bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
+bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
 			  bool *edid_corrupt)
 {
-	u8 csum;
-	struct edid *edid = (struct edid *)raw_edid;
+	struct edid *block = (struct edid *)_block;
+	enum edid_block_status status;
+	bool base = block_num == 0;
+	bool valid;
 
-	if (WARN_ON(!raw_edid))
+	if (WARN_ON(!block))
 		return false;
 
-	if (edid_fixup > 8 || edid_fixup < 0)
-		edid_fixup = 6;
-
-	if (block == 0) {
-		int score = drm_edid_header_is_valid(raw_edid);
+	status = edid_block_check(block, base);
+	if (status == EDID_BLOCK_HEADER_REPAIR) {
+		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
+		edid_header_fix(block);
 
-		if (score == 8) {
-			if (edid_corrupt)
-				*edid_corrupt = false;
-		} else if (score >= edid_fixup) {
-			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
-			 * The corrupt flag needs to be set here otherwise, the
-			 * fix-up code here will correct the problem, the
-			 * checksum is correct and the test fails
-			 */
-			if (edid_corrupt)
-				*edid_corrupt = true;
-			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
-			edid_header_fix(raw_edid);
-		} else {
-			if (edid_corrupt)
-				*edid_corrupt = true;
-			goto bad;
-		}
+		/* Retry with fixed header, update status if that worked. */
+		status = edid_block_check(block, base);
+		if (status == EDID_BLOCK_OK)
+			status = EDID_BLOCK_HEADER_FIXED;
 	}
 
-	csum = edid_block_compute_checksum(raw_edid);
-	if (csum != edid_block_get_checksum(raw_edid)) {
-		if (edid_corrupt)
+	if (edid_corrupt) {
+		/*
+		 * Unknown major version isn't corrupt but we can't use it. Only
+		 * the base block can reset edid_corrupt to false.
+		 */
+		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
+			*edid_corrupt = false;
+		else if (status != EDID_BLOCK_OK)
 			*edid_corrupt = true;
-
-		/* allow CEA to slide through, switches mangle this */
-		if (edid_block_tag(raw_edid) == CEA_EXT) {
-			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
-			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
-		} else {
-			if (print_bad_edid)
-				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
-
-			goto bad;
-		}
 	}
 
-	/* per-block-type checks */
-	switch (edid_block_tag(raw_edid)) {
-	case 0: /* base */
-		if (edid->version != 1) {
-			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
-			goto bad;
+	/* Determine whether we can use this block with this status. */
+	valid = edid_block_status_valid(status, edid_block_tag(block));
+
+	/* Some fairly random status printouts. */
+	if (status == EDID_BLOCK_CHECKSUM) {
+		if (valid) {
+			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
+				  edid_block_compute_checksum(block));
+			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
+		} else if (print_bad_edid) {
+			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
+				 edid_block_compute_checksum(block));
 		}
-
-		if (edid->revision > 4)
-			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
-		break;
-
-	default:
-		break;
+	} else if (status == EDID_BLOCK_VERSION) {
+		DRM_NOTE("EDID has major version %d, instead of 1\n",
+			 block->version);
 	}
 
-	return true;
-
-bad:
-	if (print_bad_edid) {
-		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
+	if (!valid && print_bad_edid) {
+		if (edid_is_zero(block, EDID_LENGTH)) {
 			pr_notice("EDID block is all zeroes\n");
 		} else {
 			pr_notice("Raw EDID:\n");
 			print_hex_dump(KERN_NOTICE,
 				       " \t", DUMP_PREFIX_NONE, 16, 1,
-				       raw_edid, EDID_LENGTH, false);
+				       block, EDID_LENGTH, false);
 		}
 	}
-	return false;
+
+	return valid;
 }
 EXPORT_SYMBOL(drm_edid_block_valid);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Add edid_block_check() that only checks the EDID block validity, without
any actions. Turns out it's simple and crystal clear.

Rewrite drm_edid_block_valid() around it, keeping all the functionality
fairly closely the same, warts and all. Turns out it's incredibly
complicated for a function you'd expect to be simple, with all the
fixing and printing and special casing. (Maybe we'll want to simplify it
in the future.)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
 1 file changed, 88 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 481643751d10..04eb6949c9c8 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
 }
 EXPORT_SYMBOL(drm_edid_are_equal);
 
+enum edid_block_status {
+	EDID_BLOCK_OK = 0,
+	EDID_BLOCK_NULL,
+	EDID_BLOCK_HEADER_CORRUPT,
+	EDID_BLOCK_HEADER_REPAIR,
+	EDID_BLOCK_HEADER_FIXED,
+	EDID_BLOCK_CHECKSUM,
+	EDID_BLOCK_VERSION,
+};
+
+static enum edid_block_status edid_block_check(const void *_block, bool base)
+{
+	const struct edid *block = _block;
+
+	if (!block)
+		return EDID_BLOCK_NULL;
+
+	if (base) {
+		int score = drm_edid_header_is_valid(block);
+
+		if (score < clamp(edid_fixup, 6, 8))
+			return EDID_BLOCK_HEADER_CORRUPT;
+
+		if (score < 8)
+			return EDID_BLOCK_HEADER_REPAIR;
+	}
+
+	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
+		return EDID_BLOCK_CHECKSUM;
+
+	if (base) {
+		if (block->version != 1)
+			return EDID_BLOCK_VERSION;
+	}
+
+	return EDID_BLOCK_OK;
+}
+
+static bool edid_block_status_valid(enum edid_block_status status, int tag)
+{
+	return status == EDID_BLOCK_OK ||
+		status == EDID_BLOCK_HEADER_FIXED ||
+		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
+}
+
 /**
  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
  * @raw_edid: pointer to raw EDID block
- * @block: type of block to validate (0 for base, extension otherwise)
+ * @block_num: type of block to validate (0 for base, extension otherwise)
  * @print_bad_edid: if true, dump bad EDID blocks to the console
  * @edid_corrupt: if true, the header or checksum is invalid
  *
@@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
  *
  * Return: True if the block is valid, false otherwise.
  */
-bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
+bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
 			  bool *edid_corrupt)
 {
-	u8 csum;
-	struct edid *edid = (struct edid *)raw_edid;
+	struct edid *block = (struct edid *)_block;
+	enum edid_block_status status;
+	bool base = block_num == 0;
+	bool valid;
 
-	if (WARN_ON(!raw_edid))
+	if (WARN_ON(!block))
 		return false;
 
-	if (edid_fixup > 8 || edid_fixup < 0)
-		edid_fixup = 6;
-
-	if (block == 0) {
-		int score = drm_edid_header_is_valid(raw_edid);
+	status = edid_block_check(block, base);
+	if (status == EDID_BLOCK_HEADER_REPAIR) {
+		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
+		edid_header_fix(block);
 
-		if (score == 8) {
-			if (edid_corrupt)
-				*edid_corrupt = false;
-		} else if (score >= edid_fixup) {
-			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
-			 * The corrupt flag needs to be set here otherwise, the
-			 * fix-up code here will correct the problem, the
-			 * checksum is correct and the test fails
-			 */
-			if (edid_corrupt)
-				*edid_corrupt = true;
-			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
-			edid_header_fix(raw_edid);
-		} else {
-			if (edid_corrupt)
-				*edid_corrupt = true;
-			goto bad;
-		}
+		/* Retry with fixed header, update status if that worked. */
+		status = edid_block_check(block, base);
+		if (status == EDID_BLOCK_OK)
+			status = EDID_BLOCK_HEADER_FIXED;
 	}
 
-	csum = edid_block_compute_checksum(raw_edid);
-	if (csum != edid_block_get_checksum(raw_edid)) {
-		if (edid_corrupt)
+	if (edid_corrupt) {
+		/*
+		 * Unknown major version isn't corrupt but we can't use it. Only
+		 * the base block can reset edid_corrupt to false.
+		 */
+		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
+			*edid_corrupt = false;
+		else if (status != EDID_BLOCK_OK)
 			*edid_corrupt = true;
-
-		/* allow CEA to slide through, switches mangle this */
-		if (edid_block_tag(raw_edid) == CEA_EXT) {
-			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
-			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
-		} else {
-			if (print_bad_edid)
-				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
-
-			goto bad;
-		}
 	}
 
-	/* per-block-type checks */
-	switch (edid_block_tag(raw_edid)) {
-	case 0: /* base */
-		if (edid->version != 1) {
-			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
-			goto bad;
+	/* Determine whether we can use this block with this status. */
+	valid = edid_block_status_valid(status, edid_block_tag(block));
+
+	/* Some fairly random status printouts. */
+	if (status == EDID_BLOCK_CHECKSUM) {
+		if (valid) {
+			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
+				  edid_block_compute_checksum(block));
+			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
+		} else if (print_bad_edid) {
+			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
+				 edid_block_compute_checksum(block));
 		}
-
-		if (edid->revision > 4)
-			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
-		break;
-
-	default:
-		break;
+	} else if (status == EDID_BLOCK_VERSION) {
+		DRM_NOTE("EDID has major version %d, instead of 1\n",
+			 block->version);
 	}
 
-	return true;
-
-bad:
-	if (print_bad_edid) {
-		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
+	if (!valid && print_bad_edid) {
+		if (edid_is_zero(block, EDID_LENGTH)) {
 			pr_notice("EDID block is all zeroes\n");
 		} else {
 			pr_notice("Raw EDID:\n");
 			print_hex_dump(KERN_NOTICE,
 				       " \t", DUMP_PREFIX_NONE, 16, 1,
-				       raw_edid, EDID_LENGTH, false);
+				       block, EDID_LENGTH, false);
 		}
 	}
-	return false;
+
+	return valid;
 }
 EXPORT_SYMBOL(drm_edid_block_valid);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 08/12] drm/edid: use a better variable name for EDID block read retries
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Just i is a bit terse, clarify what it's about.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 04eb6949c9c8..235d3cde2e97 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1971,25 +1971,25 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
 	int *null_edid_counter = connector ? &connector->null_edid_counter : NULL;
 	bool *edid_corrupt = connector ? &connector->edid_corrupt : NULL;
 	void *edid;
-	int i;
+	int try;
 
 	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	if (edid == NULL)
 		return NULL;
 
 	/* base block fetch */
-	for (i = 0; i < 4; i++) {
+	for (try = 0; try < 4; try++) {
 		if (get_edid_block(data, edid, 0, EDID_LENGTH))
 			goto out;
 		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
 			break;
-		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
+		if (try == 0 && edid_is_zero(edid, EDID_LENGTH)) {
 			if (null_edid_counter)
 				(*null_edid_counter)++;
 			goto carp;
 		}
 	}
-	if (i == 4)
+	if (try == 4)
 		goto carp;
 
 	return edid;
@@ -2027,7 +2027,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			      size_t len),
 	void *data)
 {
-	int i, j = 0, valid_extensions = 0;
+	int j, valid_extensions = 0;
 	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
@@ -2050,20 +2050,22 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 
 	for (j = 1; j <= edid->extensions; j++) {
 		void *block = edid + j;
+		int try;
 
-		for (i = 0; i < 4; i++) {
+		for (try = 0; try < 4; try++) {
 			if (get_edid_block(data, block, j, EDID_LENGTH))
 				goto out;
 			if (drm_edid_block_valid(block, j, false, NULL))
 				break;
 		}
 
-		if (i == 4)
+		if (try == 4)
 			valid_extensions--;
 	}
 
 	if (valid_extensions != edid->extensions) {
 		struct edid *base;
+		int i;
 
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 08/12] drm/edid: use a better variable name for EDID block read retries
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Just i is a bit terse, clarify what it's about.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 04eb6949c9c8..235d3cde2e97 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1971,25 +1971,25 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
 	int *null_edid_counter = connector ? &connector->null_edid_counter : NULL;
 	bool *edid_corrupt = connector ? &connector->edid_corrupt : NULL;
 	void *edid;
-	int i;
+	int try;
 
 	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	if (edid == NULL)
 		return NULL;
 
 	/* base block fetch */
-	for (i = 0; i < 4; i++) {
+	for (try = 0; try < 4; try++) {
 		if (get_edid_block(data, edid, 0, EDID_LENGTH))
 			goto out;
 		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
 			break;
-		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
+		if (try == 0 && edid_is_zero(edid, EDID_LENGTH)) {
 			if (null_edid_counter)
 				(*null_edid_counter)++;
 			goto carp;
 		}
 	}
-	if (i == 4)
+	if (try == 4)
 		goto carp;
 
 	return edid;
@@ -2027,7 +2027,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			      size_t len),
 	void *data)
 {
-	int i, j = 0, valid_extensions = 0;
+	int j, valid_extensions = 0;
 	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
@@ -2050,20 +2050,22 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 
 	for (j = 1; j <= edid->extensions; j++) {
 		void *block = edid + j;
+		int try;
 
-		for (i = 0; i < 4; i++) {
+		for (try = 0; try < 4; try++) {
 			if (get_edid_block(data, block, j, EDID_LENGTH))
 				goto out;
 			if (drm_edid_block_valid(block, j, false, NULL))
 				break;
 		}
 
-		if (i == 4)
+		if (try == 4)
 			valid_extensions--;
 	}
 
 	if (valid_extensions != edid->extensions) {
 		struct edid *base;
+		int i;
 
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 09/12] drm/edid: simplify block check when filtering invalid blocks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

There's no need to handle complicated scenarios or debug log when
filtering blocks that have already been identified as invalid. Simplify
by adding an edid_block_valid() helper that operates on const data and
prints nothing.

(Finally, here's the justification for the previously added separate
edid_block_status_valid() function!)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 235d3cde2e97..a1be5c3a80e5 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1713,6 +1713,12 @@ static bool edid_block_status_valid(enum edid_block_status status, int tag)
 		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
 }
 
+static bool edid_block_valid(const void *block, bool base)
+{
+	return edid_block_status_valid(edid_block_check(block, base),
+				       edid_block_tag(block));
+}
+
 /**
  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
  * @raw_edid: pointer to raw EDID block
@@ -2081,7 +2087,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		for (i = 0; i <= edid->extensions; i++) {
 			void *block = edid + i;
 
-			if (!drm_edid_block_valid(block, i, false, NULL))
+			if (!edid_block_valid(block, i == 0))
 				continue;
 
 			memcpy(base, block, EDID_LENGTH);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 09/12] drm/edid: simplify block check when filtering invalid blocks
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

There's no need to handle complicated scenarios or debug log when
filtering blocks that have already been identified as invalid. Simplify
by adding an edid_block_valid() helper that operates on const data and
prints nothing.

(Finally, here's the justification for the previously added separate
edid_block_status_valid() function!)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 235d3cde2e97..a1be5c3a80e5 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1713,6 +1713,12 @@ static bool edid_block_status_valid(enum edid_block_status status, int tag)
 		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
 }
 
+static bool edid_block_valid(const void *block, bool base)
+{
+	return edid_block_status_valid(edid_block_check(block, base),
+				       edid_block_tag(block));
+}
+
 /**
  * drm_edid_block_valid - Sanity check the EDID block (base or extension)
  * @raw_edid: pointer to raw EDID block
@@ -2081,7 +2087,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		for (i = 0; i <= edid->extensions; i++) {
 			void *block = edid + i;
 
-			if (!drm_edid_block_valid(block, i, false, NULL))
+			if (!edid_block_valid(block, i == 0))
 				continue;
 
 			memcpy(base, block, EDID_LENGTH);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 10/12] drm/edid: split out invalid block filtering to a separate function
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

It's such a special case there's no point in keeping it inline in the
happy day scenario, confusing matters.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 52 ++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a1be5c3a80e5..dee95332d7e1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1821,6 +1821,33 @@ bool drm_edid_is_valid(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
+static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
+					       int valid_extensions)
+{
+	struct edid *new, *base;
+	int i;
+
+	new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
+	if (!new)
+		goto out;
+
+	base = new;
+	for (i = 0; i <= edid->extensions; i++) {
+		const void *block = edid + i;
+
+		if (edid_block_valid(block, i == 0))
+			memcpy(base++, block, EDID_LENGTH);
+	}
+
+	new->checksum += new->extensions - valid_extensions;
+	new->extensions = valid_extensions;
+
+out:
+	kfree(edid);
+
+	return new;
+}
+
 #define DDC_SEGMENT_ADDR 0x30
 /**
  * drm_do_probe_ddc_edid() - get EDID information via I2C
@@ -2070,32 +2097,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	}
 
 	if (valid_extensions != edid->extensions) {
-		struct edid *base;
-		int i;
-
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid->checksum += edid->extensions - valid_extensions;
-		edid->extensions = valid_extensions;
-
-		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
-				    GFP_KERNEL);
-		if (!new)
-			goto out;
-
-		base = new;
-		for (i = 0; i <= edid->extensions; i++) {
-			void *block = edid + i;
-
-			if (!edid_block_valid(block, i == 0))
-				continue;
-
-			memcpy(base, block, EDID_LENGTH);
-			base++;
-		}
-
-		kfree(edid);
-		edid = new;
+		edid = edid_filter_invalid_blocks(edid, valid_extensions);
 	}
 
 	return edid;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 10/12] drm/edid: split out invalid block filtering to a separate function
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

It's such a special case there's no point in keeping it inline in the
happy day scenario, confusing matters.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 52 ++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a1be5c3a80e5..dee95332d7e1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1821,6 +1821,33 @@ bool drm_edid_is_valid(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
+static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
+					       int valid_extensions)
+{
+	struct edid *new, *base;
+	int i;
+
+	new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
+	if (!new)
+		goto out;
+
+	base = new;
+	for (i = 0; i <= edid->extensions; i++) {
+		const void *block = edid + i;
+
+		if (edid_block_valid(block, i == 0))
+			memcpy(base++, block, EDID_LENGTH);
+	}
+
+	new->checksum += new->extensions - valid_extensions;
+	new->extensions = valid_extensions;
+
+out:
+	kfree(edid);
+
+	return new;
+}
+
 #define DDC_SEGMENT_ADDR 0x30
 /**
  * drm_do_probe_ddc_edid() - get EDID information via I2C
@@ -2070,32 +2097,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	}
 
 	if (valid_extensions != edid->extensions) {
-		struct edid *base;
-		int i;
-
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid->checksum += edid->extensions - valid_extensions;
-		edid->extensions = valid_extensions;
-
-		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
-				    GFP_KERNEL);
-		if (!new)
-			goto out;
-
-		base = new;
-		for (i = 0; i <= edid->extensions; i++) {
-			void *block = edid + i;
-
-			if (!edid_block_valid(block, i == 0))
-				continue;
-
-			memcpy(base, block, EDID_LENGTH);
-			base++;
-		}
-
-		kfree(edid);
-		edid = new;
+		edid = edid_filter_invalid_blocks(edid, valid_extensions);
 	}
 
 	return edid;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 11/12] drm/edid: track invalid blocks in drm_do_get_edid()
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Track invalid blocks instead of valid extensions to minimize impact on
the happy day scenario, and hide the details in the separate function.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dee95332d7e1..d0a76781ed19 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1822,9 +1822,10 @@ bool drm_edid_is_valid(struct edid *edid)
 EXPORT_SYMBOL(drm_edid_is_valid);
 
 static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int valid_extensions)
+					       int invalid_blocks)
 {
 	struct edid *new, *base;
+	int valid_extensions = edid->extensions - invalid_blocks;
 	int i;
 
 	new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
@@ -2060,7 +2061,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			      size_t len),
 	void *data)
 {
-	int j, valid_extensions = 0;
+	int j, invalid_blocks = 0;
 	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
@@ -2071,12 +2072,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (!edid)
 		return NULL;
 
-	/* if there's no extensions or no connector, we're done */
-	valid_extensions = edid->extensions;
-	if (valid_extensions == 0)
+	if (edid->extensions == 0)
 		return edid;
 
-	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+	new = krealloc(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
 	if (!new)
 		goto out;
 	edid = new;
@@ -2093,13 +2092,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		}
 
 		if (try == 4)
-			valid_extensions--;
+			invalid_blocks++;
 	}
 
-	if (valid_extensions != edid->extensions) {
+	if (invalid_blocks) {
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid = edid_filter_invalid_blocks(edid, valid_extensions);
+		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
 	}
 
 	return edid;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 11/12] drm/edid: track invalid blocks in drm_do_get_edid()
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Track invalid blocks instead of valid extensions to minimize impact on
the happy day scenario, and hide the details in the separate function.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dee95332d7e1..d0a76781ed19 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1822,9 +1822,10 @@ bool drm_edid_is_valid(struct edid *edid)
 EXPORT_SYMBOL(drm_edid_is_valid);
 
 static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
-					       int valid_extensions)
+					       int invalid_blocks)
 {
 	struct edid *new, *base;
+	int valid_extensions = edid->extensions - invalid_blocks;
 	int i;
 
 	new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
@@ -2060,7 +2061,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 			      size_t len),
 	void *data)
 {
-	int j, valid_extensions = 0;
+	int j, invalid_blocks = 0;
 	struct edid *edid, *new, *override;
 
 	override = drm_get_override_edid(connector);
@@ -2071,12 +2072,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	if (!edid)
 		return NULL;
 
-	/* if there's no extensions or no connector, we're done */
-	valid_extensions = edid->extensions;
-	if (valid_extensions == 0)
+	if (edid->extensions == 0)
 		return edid;
 
-	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+	new = krealloc(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
 	if (!new)
 		goto out;
 	edid = new;
@@ -2093,13 +2092,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		}
 
 		if (try == 4)
-			valid_extensions--;
+			invalid_blocks++;
 	}
 
-	if (valid_extensions != edid->extensions) {
+	if (invalid_blocks) {
 		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
 
-		edid = edid_filter_invalid_blocks(edid, valid_extensions);
+		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
 	}
 
 	return edid;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 12/12] drm/edid: reduce magic when updating the EDID block checksum
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-29 18:42   ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The code modifying the EDID block should not need to do tricks to fix
the checksum. We have a function for computing the checksum, use it.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d0a76781ed19..d2dfab28b5b7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1840,8 +1840,8 @@ static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
 			memcpy(base++, block, EDID_LENGTH);
 	}
 
-	new->checksum += new->extensions - valid_extensions;
 	new->extensions = valid_extensions;
+	new->checksum = edid_block_compute_checksum(new);
 
 out:
 	kfree(edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] [PATCH 12/12] drm/edid: reduce magic when updating the EDID block checksum
@ 2022-03-29 18:42   ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-29 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

The code modifying the EDID block should not need to do tricks to fix
the checksum. We have a function for computing the checksum, use it.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d0a76781ed19..d2dfab28b5b7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1840,8 +1840,8 @@ static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
 			memcpy(base++, block, EDID_LENGTH);
 	}
 
-	new->checksum += new->extensions - valid_extensions;
 	new->extensions = valid_extensions;
+	new->checksum = edid_block_compute_checksum(new);
 
 out:
 	kfree(edid);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/edid: cleanup and refactoring around validity checks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
                   ` (12 preceding siblings ...)
  (?)
@ 2022-03-29 19:33 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-03-29 19:33 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

== Series Details ==

Series: drm/edid: cleanup and refactoring around validity checks
URL   : https://patchwork.freedesktop.org/series/101931/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16: error: incompatible types in comparison expression (different type sizes):
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf



^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Intel-gfx] ✗ Fi.CI.DOCS: warning for drm/edid: cleanup and refactoring around validity checks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
                   ` (13 preceding siblings ...)
  (?)
@ 2022-03-29 19:37 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-03-29 19:37 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

== Series Details ==

Series: drm/edid: cleanup and refactoring around validity checks
URL   : https://patchwork.freedesktop.org/series/101931/
State : warning

== Summary ==

$ make htmldocs 2>&1 > /dev/null | grep i915
./drivers/gpu/drm/i915/display/intel_drrs.c:1: warning: 'intel_drrs_enable' not found
./drivers/gpu/drm/i915/display/intel_drrs.c:1: warning: 'intel_drrs_disable' not found



^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/edid: cleanup and refactoring around validity checks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
                   ` (14 preceding siblings ...)
  (?)
@ 2022-03-29 20:09 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-03-29 20:09 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 12635 bytes --]

== Series Details ==

Series: drm/edid: cleanup and refactoring around validity checks
URL   : https://patchwork.freedesktop.org/series/101931/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11416 -> Patchwork_22724
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/index.html

Participating hosts (43 -> 44)
------------------------------

  Additional (6): fi-tgl-u2 fi-skl-guc bat-adlm-1 fi-cfl-8700k bat-adlp-4 fi-ivb-3770 
  Missing    (5): fi-kbl-soraka shard-tglu fi-bsw-cyan shard-rkl fi-bdw-samus 

Known issues
------------

  Here are the changes found in Patchwork_22724 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_basic@query-info:
    - fi-bsw-kefka:       NOTRUN -> [SKIP][1] ([fdo#109271]) +17 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-bsw-kefka/igt@amdgpu/amd_basic@query-info.html

  * igt@amdgpu/amd_basic@semaphore:
    - fi-hsw-4770:        NOTRUN -> [SKIP][2] ([fdo#109271] / [fdo#109315]) +17 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-hsw-4770/igt@amdgpu/amd_basic@semaphore.html

  * igt@amdgpu/amd_basic@userptr:
    - fi-cfl-8700k:       NOTRUN -> [SKIP][3] ([fdo#109271]) +29 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-cfl-8700k/igt@amdgpu/amd_basic@userptr.html

  * igt@gem_huc_copy@huc-copy:
    - fi-tgl-u2:          NOTRUN -> [SKIP][4] ([i915#2190])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@gem_huc_copy@huc-copy.html
    - fi-cfl-8700k:       NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#2190])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-cfl-8700k/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@random-engines:
    - fi-skl-guc:         NOTRUN -> [SKIP][6] ([fdo#109271] / [i915#4613]) +3 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-skl-guc/igt@gem_lmem_swapping@random-engines.html
    - fi-ivb-3770:        NOTRUN -> [SKIP][7] ([fdo#109271]) +36 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-ivb-3770/igt@gem_lmem_swapping@random-engines.html
    - fi-cfl-8700k:       NOTRUN -> [SKIP][8] ([fdo#109271] / [i915#4613]) +3 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-cfl-8700k/igt@gem_lmem_swapping@random-engines.html

  * igt@gem_lmem_swapping@verify-random:
    - fi-tgl-u2:          NOTRUN -> [SKIP][9] ([i915#4613]) +3 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@gem_lmem_swapping@verify-random.html

  * igt@i915_selftest@live@hangcheck:
    - fi-snb-2600:        [PASS][10] -> [INCOMPLETE][11] ([i915#3921])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-snb-2600/igt@i915_selftest@live@hangcheck.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-snb-2600/igt@i915_selftest@live@hangcheck.html

  * igt@kms_busy@basic@flip:
    - fi-tgl-u2:          NOTRUN -> [DMESG-WARN][12] ([i915#402])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@kms_busy@basic@flip.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-tgl-u2:          NOTRUN -> [SKIP][13] ([fdo#109284] / [fdo#111827]) +8 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@kms_chamelium@common-hpd-after-suspend.html
    - fi-skl-guc:         NOTRUN -> [SKIP][14] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-skl-guc/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-cfl-8700k:       NOTRUN -> [SKIP][15] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-cfl-8700k/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@dp-hpd-fast:
    - fi-ivb-3770:        NOTRUN -> [SKIP][16] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-ivb-3770/igt@kms_chamelium@dp-hpd-fast.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-tgl-u2:          NOTRUN -> [SKIP][17] ([i915#4103]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_force_connector_basic@force-load-detect:
    - fi-tgl-u2:          NOTRUN -> [SKIP][18] ([fdo#109285])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-skl-guc:         NOTRUN -> [SKIP][19] ([fdo#109271] / [i915#533])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-skl-guc/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html
    - fi-cfl-8700k:       NOTRUN -> [SKIP][20] ([fdo#109271] / [i915#533])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-cfl-8700k/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_psr@primary_mmap_gtt:
    - fi-skl-guc:         NOTRUN -> [SKIP][21] ([fdo#109271]) +29 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-skl-guc/igt@kms_psr@primary_mmap_gtt.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-tgl-u2:          NOTRUN -> [SKIP][22] ([i915#3555])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-tgl-u2/igt@kms_setmode@basic-clone-single-crtc.html

  * igt@runner@aborted:
    - bat-adlp-4:         NOTRUN -> [FAIL][23] ([i915#5457])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-adlp-4/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@i915_pm_rps@basic-api:
    - {fi-jsl-1}:         [DMESG-WARN][24] -> [PASS][25]
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-jsl-1/igt@i915_pm_rps@basic-api.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-jsl-1/igt@i915_pm_rps@basic-api.html

  * igt@i915_selftest@live@execlists:
    - fi-bsw-kefka:       [INCOMPLETE][26] ([i915#2940]) -> [PASS][27]
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-bsw-kefka/igt@i915_selftest@live@execlists.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-bsw-kefka/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@gt_lrc:
    - {bat-adlp-6}:       [INCOMPLETE][28] -> [PASS][29]
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/bat-adlp-6/igt@i915_selftest@live@gt_lrc.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-adlp-6/igt@i915_selftest@live@gt_lrc.html

  * igt@i915_selftest@live@hangcheck:
    - fi-hsw-4770:        [INCOMPLETE][30] ([i915#4785]) -> [PASS][31]
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-hsw-4770/igt@i915_selftest@live@hangcheck.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-hsw-4770/igt@i915_selftest@live@hangcheck.html
    - {fi-hsw-g3258}:     [INCOMPLETE][32] ([i915#3303] / [i915#4785]) -> [PASS][33]
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-hsw-g3258/igt@i915_selftest@live@hangcheck.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-hsw-g3258/igt@i915_selftest@live@hangcheck.html
    - {fi-ehl-2}:         [INCOMPLETE][34] -> [PASS][35]
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/fi-ehl-2/igt@i915_selftest@live@hangcheck.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/fi-ehl-2/igt@i915_selftest@live@hangcheck.html

  * igt@i915_selftest@live@requests:
    - {bat-rpls-2}:       [DMESG-FAIL][36] ([i915#5087]) -> [PASS][37]
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/bat-rpls-2/igt@i915_selftest@live@requests.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-rpls-2/igt@i915_selftest@live@requests.html

  * igt@i915_selftest@live@workarounds:
    - {bat-adlp-6}:       [DMESG-WARN][38] ([i915#5068]) -> [PASS][39]
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/bat-adlp-6/igt@i915_selftest@live@workarounds.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-adlp-6/igt@i915_selftest@live@workarounds.html

  * igt@kms_busy@basic@flip:
    - {bat-adlp-6}:       [DMESG-WARN][40] ([i915#3576]) -> [PASS][41]
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/bat-adlp-6/igt@kms_busy@basic@flip.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-adlp-6/igt@kms_busy@basic@flip.html
    - {bat-dg2-9}:        [DMESG-WARN][42] ([i915#5291]) -> [PASS][43]
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/bat-dg2-9/igt@kms_busy@basic@flip.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/bat-dg2-9/igt@kms_busy@basic@flip.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#2940]: https://gitlab.freedesktop.org/drm/intel/issues/2940
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3303]: https://gitlab.freedesktop.org/drm/intel/issues/3303
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3576]: https://gitlab.freedesktop.org/drm/intel/issues/3576
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4391]: https://gitlab.freedesktop.org/drm/intel/issues/4391
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4785]: https://gitlab.freedesktop.org/drm/intel/issues/4785
  [i915#4897]: https://gitlab.freedesktop.org/drm/intel/issues/4897
  [i915#5068]: https://gitlab.freedesktop.org/drm/intel/issues/5068
  [i915#5087]: https://gitlab.freedesktop.org/drm/intel/issues/5087
  [i915#5127]: https://gitlab.freedesktop.org/drm/intel/issues/5127
  [i915#5195]: https://gitlab.freedesktop.org/drm/intel/issues/5195
  [i915#5274]: https://gitlab.freedesktop.org/drm/intel/issues/5274
  [i915#5291]: https://gitlab.freedesktop.org/drm/intel/issues/5291
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5457]: https://gitlab.freedesktop.org/drm/intel/issues/5457


Build changes
-------------

  * Linux: CI_DRM_11416 -> Patchwork_22724

  CI-20190529: 20190529
  CI_DRM_11416: 1dc2c6953e2689a0e5b7cca8450da14059d35f03 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6399: 9ba6cb16f04319226383b57975db203561c75781 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_22724: fccd3427bc62337965079e999b1db83f8299a7cf @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

fccd3427bc62 drm/edid: reduce magic when updating the EDID block checksum
c635d1b18fac drm/edid: track invalid blocks in drm_do_get_edid()
d0a10247f75e drm/edid: split out invalid block filtering to a separate function
2624bac2816e drm/edid: simplify block check when filtering invalid blocks
e19a3f31f061 drm/edid: use a better variable name for EDID block read retries
a0f9a47ba4a3 drm/edid: split drm_edid_block_valid() to check and act parts
a49f957a6de0 drm/edid: split out edid_header_fix()
5f29030bb854 drm/edid: clean up edid_is_zero()
cbc37bdb1a76 drm/edid: make drm_edid_header_is_valid() accept void pointer
aefc5a2f5b23 drm/edid: add edid_block_tag() helper to get the EDID extension tag
396af50ebe99 drm/edid: clean up EDID block checksum functions
43d46ae821d8 drm/edid: use struct edid * in drm_do_get_edid()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/index.html

[-- Attachment #2: Type: text/html, Size: 14775 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/edid: cleanup and refactoring around validity checks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
                   ` (15 preceding siblings ...)
  (?)
@ 2022-03-29 21:26 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-03-29 21:26 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30280 bytes --]

== Series Details ==

Series: drm/edid: cleanup and refactoring around validity checks
URL   : https://patchwork.freedesktop.org/series/101931/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11416_full -> Patchwork_22724_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Participating hosts (11 -> 10)
------------------------------

  Missing    (1): shard-tglu 

Known issues
------------

  Here are the changes found in Patchwork_22724_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@legacy-engines-queued:
    - shard-snb:          NOTRUN -> [SKIP][1] ([fdo#109271] / [i915#1099]) +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-snb2/igt@gem_ctx_persistence@legacy-engines-queued.html

  * igt@gem_ctx_persistence@smoketest:
    - shard-apl:          NOTRUN -> [FAIL][2] ([i915#5099])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl6/igt@gem_ctx_persistence@smoketest.html

  * igt@gem_ctx_sseu@invalid-sseu:
    - shard-tglb:         NOTRUN -> [SKIP][3] ([i915#280])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@gem_ctx_sseu@invalid-sseu.html

  * igt@gem_eio@in-flight-contexts-immediate:
    - shard-tglb:         [PASS][4] -> [TIMEOUT][5] ([i915#3063])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-tglb1/igt@gem_eio@in-flight-contexts-immediate.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb3/igt@gem_eio@in-flight-contexts-immediate.html

  * igt@gem_eio@unwedge-stress:
    - shard-iclb:         [PASS][6] -> [TIMEOUT][7] ([i915#2481] / [i915#3070])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb1/igt@gem_eio@unwedge-stress.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb6/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_capture@pi@rcs0:
    - shard-skl:          [PASS][8] -> [INCOMPLETE][9] ([i915#4547])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl2/igt@gem_exec_capture@pi@rcs0.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl3/igt@gem_exec_capture@pi@rcs0.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-iclb:         [PASS][10] -> [FAIL][11] ([i915#2842]) +1 similar issue
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb7/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb4/igt@gem_exec_fair@basic-pace-solo@rcs0.html
    - shard-glk:          [PASS][12] -> [FAIL][13] ([i915#2842])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-glk8/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-glk6/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_exec_schedule@submit-early-slice@vcs0:
    - shard-skl:          NOTRUN -> [INCOMPLETE][14] ([i915#3797])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl1/igt@gem_exec_schedule@submit-early-slice@vcs0.html

  * igt@gem_lmem_swapping@parallel-random:
    - shard-tglb:         NOTRUN -> [SKIP][15] ([i915#4613])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@gem_lmem_swapping@parallel-random.html

  * igt@gem_lmem_swapping@verify-random:
    - shard-skl:          NOTRUN -> [SKIP][16] ([fdo#109271] / [i915#4613]) +2 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@gem_lmem_swapping@verify-random.html

  * igt@gem_pread@exhaustion:
    - shard-snb:          NOTRUN -> [WARN][17] ([i915#2658])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-snb2/igt@gem_pread@exhaustion.html

  * igt@gem_pxp@reject-modify-context-protection-off-2:
    - shard-iclb:         NOTRUN -> [SKIP][18] ([i915#4270])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@gem_pxp@reject-modify-context-protection-off-2.html

  * igt@gem_pxp@verify-pxp-stale-buf-optout-execution:
    - shard-tglb:         NOTRUN -> [SKIP][19] ([i915#4270])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@gem_pxp@verify-pxp-stale-buf-optout-execution.html

  * igt@gem_render_copy@linear-to-vebox-y-tiled:
    - shard-iclb:         NOTRUN -> [SKIP][20] ([i915#768])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@gem_render_copy@linear-to-vebox-y-tiled.html

  * igt@gen7_exec_parse@basic-allowed:
    - shard-tglb:         NOTRUN -> [SKIP][21] ([fdo#109289]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@gen7_exec_parse@basic-allowed.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [PASS][22] -> [DMESG-WARN][23] ([i915#1436] / [i915#716])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl9/igt@gen9_exec_parse@allowed-single.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl9/igt@gen9_exec_parse@allowed-single.html

  * igt@gen9_exec_parse@basic-rejected-ctx-param:
    - shard-iclb:         NOTRUN -> [SKIP][24] ([i915#2856])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@gen9_exec_parse@basic-rejected-ctx-param.html

  * igt@gen9_exec_parse@cmd-crossing-page:
    - shard-tglb:         NOTRUN -> [SKIP][25] ([i915#2527] / [i915#2856])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@gen9_exec_parse@cmd-crossing-page.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [PASS][26] -> [FAIL][27] ([i915#454])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb8/igt@i915_pm_dc@dc6-dpms.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_selftest@live@gt_lrc:
    - shard-tglb:         NOTRUN -> [DMESG-FAIL][28] ([i915#2373])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@i915_selftest@live@gt_lrc.html

  * igt@i915_selftest@live@gt_pm:
    - shard-tglb:         NOTRUN -> [DMESG-FAIL][29] ([i915#1759])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@i915_selftest@live@gt_pm.html

  * igt@i915_suspend@sysfs-reader:
    - shard-skl:          [PASS][30] -> [INCOMPLETE][31] ([i915#4817])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl6/igt@i915_suspend@sysfs-reader.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl1/igt@i915_suspend@sysfs-reader.html

  * igt@kms_async_flips@crc:
    - shard-skl:          NOTRUN -> [FAIL][32] ([i915#4272])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl4/igt@kms_async_flips@crc.html

  * igt@kms_big_fb@4-tiled-8bpp-rotate-180:
    - shard-tglb:         NOTRUN -> [SKIP][33] ([i915#5286])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_big_fb@4-tiled-8bpp-rotate-180.html

  * igt@kms_big_fb@linear-32bpp-rotate-270:
    - shard-tglb:         NOTRUN -> [SKIP][34] ([fdo#111614])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_big_fb@linear-32bpp-rotate-270.html

  * igt@kms_big_fb@linear-8bpp-rotate-270:
    - shard-iclb:         NOTRUN -> [SKIP][35] ([fdo#110725] / [fdo#111614])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_big_fb@linear-8bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-async-flip:
    - shard-skl:          NOTRUN -> [FAIL][36] ([i915#3743])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl4/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-async-flip.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-180:
    - shard-skl:          [PASS][37] -> [DMESG-WARN][38] ([i915#1982])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl10/igt@kms_big_fb@yf-tiled-16bpp-rotate-180.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl2/igt@kms_big_fb@yf-tiled-16bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-270:
    - shard-apl:          NOTRUN -> [SKIP][39] ([fdo#109271]) +35 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl6/igt@kms_big_fb@yf-tiled-16bpp-rotate-270.html

  * igt@kms_big_fb@yf-tiled-addfb-size-offset-overflow:
    - shard-tglb:         NOTRUN -> [SKIP][40] ([fdo#111615])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_big_fb@yf-tiled-addfb-size-offset-overflow.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip:
    - shard-skl:          NOTRUN -> [SKIP][41] ([fdo#109271] / [i915#3777]) +3 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip.html

  * igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][42] ([fdo#109278]) +3 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs.html

  * igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][43] ([i915#3689] / [i915#3886])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_mc_ccs:
    - shard-skl:          NOTRUN -> [SKIP][44] ([fdo#109271] / [i915#3886]) +5 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-rotation-90-yf_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][45] ([fdo#111615] / [i915#3689])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_ccs@pipe-b-bad-rotation-90-yf_tiled_ccs.html

  * igt@kms_ccs@pipe-c-random-ccs-data-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][46] ([fdo#109271] / [i915#3886])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl6/igt@kms_ccs@pipe-c-random-ccs-data-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-d-bad-aux-stride-y_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][47] ([i915#3689]) +1 similar issue
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_ccs@pipe-d-bad-aux-stride-y_tiled_ccs.html

  * igt@kms_ccs@pipe-d-random-ccs-data-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][48] ([fdo#109271]) +9 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl7/igt@kms_ccs@pipe-d-random-ccs-data-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_chamelium@vga-hpd:
    - shard-skl:          NOTRUN -> [SKIP][49] ([fdo#109271] / [fdo#111827]) +16 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl1/igt@kms_chamelium@vga-hpd.html

  * igt@kms_color_chamelium@pipe-b-ctm-blue-to-red:
    - shard-apl:          NOTRUN -> [SKIP][50] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl6/igt@kms_color_chamelium@pipe-b-ctm-blue-to-red.html
    - shard-kbl:          NOTRUN -> [SKIP][51] ([fdo#109271] / [fdo#111827])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl7/igt@kms_color_chamelium@pipe-b-ctm-blue-to-red.html

  * igt@kms_color_chamelium@pipe-c-ctm-0-25:
    - shard-tglb:         NOTRUN -> [SKIP][52] ([fdo#109284] / [fdo#111827]) +3 similar issues
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_color_chamelium@pipe-c-ctm-0-25.html

  * igt@kms_color_chamelium@pipe-d-ctm-negative:
    - shard-iclb:         NOTRUN -> [SKIP][53] ([fdo#109278] / [fdo#109284] / [fdo#111827]) +1 similar issue
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_color_chamelium@pipe-d-ctm-negative.html

  * igt@kms_content_protection@dp-mst-lic-type-1:
    - shard-tglb:         NOTRUN -> [SKIP][54] ([i915#3116] / [i915#3299])
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_content_protection@dp-mst-lic-type-1.html

  * igt@kms_cursor_crc@pipe-b-cursor-32x10-sliding:
    - shard-tglb:         NOTRUN -> [SKIP][55] ([i915#3359]) +1 similar issue
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_cursor_crc@pipe-b-cursor-32x10-sliding.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-varying-size:
    - shard-tglb:         NOTRUN -> [SKIP][56] ([i915#4103])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-varying-size.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-iclb:         [PASS][57] -> [FAIL][58] ([i915#2346])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb8/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-mmap-wc-4tiled:
    - shard-tglb:         NOTRUN -> [SKIP][59] ([i915#5287])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_draw_crc@draw-method-xrgb2101010-mmap-wc-4tiled.html

  * igt@kms_flip@2x-dpms-vs-vblank-race-interruptible:
    - shard-tglb:         NOTRUN -> [SKIP][60] ([fdo#109274] / [fdo#111825]) +2 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_flip@2x-dpms-vs-vblank-race-interruptible.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2:
    - shard-glk:          [PASS][61] -> [FAIL][62] ([i915#79])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-glk8/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling:
    - shard-glk:          [PASS][63] -> [FAIL][64] ([i915#4911]) +1 similar issue
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-glk4/igt@kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-glk8/igt@kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-pwrite:
    - shard-iclb:         NOTRUN -> [SKIP][65] ([fdo#109280])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [PASS][66] -> [DMESG-WARN][67] ([i915#180]) +2 similar issues
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl4/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-shrfb-fliptrack-mmap-gtt:
    - shard-skl:          NOTRUN -> [SKIP][68] ([fdo#109271]) +218 similar issues
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@kms_frontbuffer_tracking@fbcpsr-1p-shrfb-fliptrack-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-cpu:
    - shard-tglb:         NOTRUN -> [SKIP][69] ([fdo#109280] / [fdo#111825]) +6 similar issues
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-cpu.html

  * igt@kms_hdr@bpc-switch-dpms@bpc-switch-dpms-edp-1-pipe-a:
    - shard-skl:          NOTRUN -> [FAIL][70] ([i915#1188])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl4/igt@kms_hdr@bpc-switch-dpms@bpc-switch-dpms-edp-1-pipe-a.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-d:
    - shard-skl:          NOTRUN -> [SKIP][71] ([fdo#109271] / [i915#533]) +1 similar issue
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl1/igt@kms_pipe_crc_basic@hang-read-crc-pipe-d.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes:
    - shard-apl:          [PASS][72] -> [DMESG-WARN][73] ([i915#180]) +4 similar issues
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-apl1/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl4/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max:
    - shard-skl:          NOTRUN -> [FAIL][74] ([fdo#108145] / [i915#265]) +1 similar issue
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb:
    - shard-skl:          NOTRUN -> [FAIL][75] ([i915#265])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl4/igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb.html

  * igt@kms_plane_lowres@pipe-a-tiling-4:
    - shard-tglb:         NOTRUN -> [SKIP][76] ([i915#5288])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_plane_lowres@pipe-a-tiling-4.html

  * igt@kms_plane_lowres@pipe-b-tiling-y:
    - shard-iclb:         NOTRUN -> [SKIP][77] ([i915#3536])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_plane_lowres@pipe-b-tiling-y.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area:
    - shard-skl:          NOTRUN -> [SKIP][78] ([fdo#109271] / [i915#658])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl10/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area.html

  * igt@kms_psr2_su@frontbuffer-xrgb8888:
    - shard-apl:          NOTRUN -> [SKIP][79] ([fdo#109271] / [i915#658])
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl8/igt@kms_psr2_su@frontbuffer-xrgb8888.html
    - shard-iclb:         NOTRUN -> [SKIP][80] ([fdo#109642] / [fdo#111068] / [i915#658])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_psr2_su@frontbuffer-xrgb8888.html

  * igt@kms_psr@psr2_primary_mmap_gtt:
    - shard-tglb:         NOTRUN -> [FAIL][81] ([i915#132] / [i915#3467])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_psr@psr2_primary_mmap_gtt.html

  * igt@kms_psr@psr2_sprite_render:
    - shard-iclb:         [PASS][82] -> [SKIP][83] ([fdo#109441]) +1 similar issue
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@kms_psr@psr2_sprite_render.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb8/igt@kms_psr@psr2_sprite_render.html

  * igt@kms_rotation_crc@primary-y-tiled-reflect-x-0:
    - shard-snb:          NOTRUN -> [SKIP][84] ([fdo#109271]) +73 similar issues
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-snb2/igt@kms_rotation_crc@primary-y-tiled-reflect-x-0.html

  * igt@kms_vblank@pipe-b-ts-continuation-suspend:
    - shard-kbl:          [PASS][85] -> [INCOMPLETE][86] ([i915#2828])
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-kbl6/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl4/igt@kms_vblank@pipe-b-ts-continuation-suspend.html

  * igt@kms_writeback@writeback-pixel-formats:
    - shard-tglb:         NOTRUN -> [SKIP][87] ([i915#2437])
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@kms_writeback@writeback-pixel-formats.html

  * igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame:
    - shard-iclb:         NOTRUN -> [SKIP][88] ([i915#2530])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@nouveau_crc@pipe-c-ctx-flip-skip-current-frame.html

  * igt@perf_pmu@rc6-suspend:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][89] ([i915#180])
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl7/igt@perf_pmu@rc6-suspend.html

  * igt@prime_nv_api@i915_nv_import_twice:
    - shard-iclb:         NOTRUN -> [SKIP][90] ([fdo#109291])
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@prime_nv_api@i915_nv_import_twice.html

  * igt@prime_nv_pcopy@test3_2:
    - shard-tglb:         NOTRUN -> [SKIP][91] ([fdo#109291])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@prime_nv_pcopy@test3_2.html

  * igt@sysfs_clients@fair-7:
    - shard-iclb:         NOTRUN -> [SKIP][92] ([i915#2994])
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@sysfs_clients@fair-7.html

  * igt@sysfs_clients@sema-10:
    - shard-skl:          NOTRUN -> [SKIP][93] ([fdo#109271] / [i915#2994]) +2 similar issues
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl1/igt@sysfs_clients@sema-10.html

  * igt@sysfs_clients@split-25:
    - shard-tglb:         NOTRUN -> [SKIP][94] ([i915#2994])
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@sysfs_clients@split-25.html

  * igt@tools_test@sysfs_l3_parity:
    - shard-tglb:         NOTRUN -> [SKIP][95] ([fdo#109307])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-tglb6/igt@tools_test@sysfs_l3_parity.html

  
#### Possible fixes ####

  * igt@gem_caching@reads:
    - shard-glk:          [DMESG-WARN][96] ([i915#118]) -> [PASS][97]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-glk5/igt@gem_caching@reads.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-glk1/igt@gem_caching@reads.html

  * igt@gem_ctx_isolation@preservation-s3@rcs0:
    - shard-kbl:          [DMESG-WARN][98] ([i915#180]) -> [PASS][99] +1 similar issue
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-kbl6/igt@gem_ctx_isolation@preservation-s3@rcs0.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-kbl4/igt@gem_ctx_isolation@preservation-s3@rcs0.html

  * igt@gem_exec_balancer@parallel-balancer:
    - shard-iclb:         [SKIP][100] ([i915#4525]) -> [PASS][101]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb5/igt@gem_exec_balancer@parallel-balancer.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb1/igt@gem_exec_balancer@parallel-balancer.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-apl:          [FAIL][102] ([i915#2842]) -> [PASS][103]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-apl8/igt@gem_exec_fair@basic-none@vecs0.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl4/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@kms_async_flips@alternate-sync-async-flip:
    - shard-skl:          [FAIL][104] ([i915#2521]) -> [PASS][105]
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl8/igt@kms_async_flips@alternate-sync-async-flip.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl6/igt@kms_async_flips@alternate-sync-async-flip.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling:
    - shard-iclb:         [SKIP][106] ([i915#3701]) -> [PASS][107]
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb8/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html

  * igt@kms_frontbuffer_tracking@psr-suspend:
    - shard-skl:          [INCOMPLETE][108] ([i915#123]) -> [PASS][109]
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl4/igt@kms_frontbuffer_tracking@psr-suspend.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl5/igt@kms_frontbuffer_tracking@psr-suspend.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
    - shard-apl:          [DMESG-WARN][110] ([i915#180]) -> [PASS][111] +1 similar issue
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-apl3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-apl8/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         [SKIP][112] ([fdo#109441]) -> [PASS][113]
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb5/igt@kms_psr@psr2_cursor_blt.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb2/igt@kms_psr@psr2_cursor_blt.html

  * igt@perf@polling-small-buf:
    - shard-skl:          [FAIL][114] ([i915#1722]) -> [PASS][115]
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl8/igt@perf@polling-small-buf.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl4/igt@perf@polling-small-buf.html

  
#### Warnings ####

  * igt@gem_exec_balancer@parallel:
    - shard-iclb:         [SKIP][116] ([i915#4525]) -> [DMESG-WARN][117] ([i915#5076]) +2 similar issues
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb8/igt@gem_exec_balancer@parallel.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb2/igt@gem_exec_balancer@parallel.html

  * igt@gem_exec_balancer@parallel-keep-in-fence:
    - shard-iclb:         [DMESG-WARN][118] ([i915#5076]) -> [SKIP][119] ([i915#4525])
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@gem_exec_balancer@parallel-keep-in-fence.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@gem_exec_balancer@parallel-keep-in-fence.html

  * igt@gem_exec_fair@basic-flow@rcs0:
    - shard-skl:          [SKIP][120] ([fdo#109271]) -> [SKIP][121] ([fdo#109271] / [i915#1888])
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl9/igt@gem_exec_fair@basic-flow@rcs0.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl2/igt@gem_exec_fair@basic-flow@rcs0.html

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         [SKIP][122] ([i915#658]) -> [SKIP][123] ([i915#588])
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb5/igt@i915_pm_dc@dc3co-vpb-simulation.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-iclb:         [WARN][124] ([i915#1804] / [i915#2684]) -> [WARN][125] ([i915#2684])
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb4/igt@i915_pm_rc6_residency@rc6-idle.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb2/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@kms_color_chamelium@pipe-c-degamma:
    - shard-skl:          [SKIP][126] ([fdo#109271] / [fdo#111827] / [i915#1888]) -> [SKIP][127] ([fdo#109271] / [fdo#111827])
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-skl1/igt@kms_color_chamelium@pipe-c-degamma.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-skl2/igt@kms_color_chamelium@pipe-c-degamma.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-sf:
    - shard-iclb:         [SKIP][128] ([i915#2920]) -> [SKIP][129] ([i915#658])
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@kms_psr2_sf@cursor-plane-move-continuous-sf.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb5/igt@kms_psr2_sf@cursor-plane-move-continuous-sf.html

  * igt@kms_psr2_sf@cursor-plane-update-sf:
    - shard-iclb:         [SKIP][130] ([i915#2920]) -> [SKIP][131] ([fdo#111068] / [i915#658])
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@kms_psr2_sf@cursor-plane-update-sf.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb8/igt@kms_psr2_sf@cursor-plane-update-sf.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-iclb:         [FAIL][132] ([i915#4148]) -> [SKIP][133] ([fdo#109642] / [fdo#111068] / [i915#658])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-iclb2/igt@kms_psr2_su@page_flip-p010.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/shard-iclb7/igt@kms_psr2_su@page_flip-p010.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][134], [FAIL][135], [FAIL][136], [FAIL][137], [FAIL][138], [FAIL][139], [FAIL][140], [FAIL][141], [FAIL][142], [FAIL][143], [FAIL][144], [FAIL][145], [FAIL][146], [FAIL][147], [FAIL][148]) ([i915#1436] / [i915#180] / [i915#1814] / [i915#3002] / [i915#4312] / [i915#5257]) -> ([FAIL][149], [FAIL][150], [FAIL][151], [FAIL][152], [FAIL][153], [FAIL][154], [FAIL][155], [FAIL][156], [FAIL][157], [FAIL][158], [FAIL][159], [FAIL][160], [FAIL][161], [FAIL][162], [FAIL][163], [FAIL][164], [FAIL][165]) ([fdo#109271] / [i915#1436] / [i915#180] / [i915#1814] / [i915#3002] / [i915#4312] / [i915#5257])
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-kbl7/igt@runner@aborted.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11416/shard-kbl6/igt@runner@aborted.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22724/index.html

[-- Attachment #2: Type: text/html, Size: 33578 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
@ 2022-03-30 13:05     ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 13:05 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> Mixing u8 * and struct edid * is confusing, switch to the latter.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>  1 file changed, 15 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index d79b06f7f34c..0650b9217aa2 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	void *data)
>  {
>  	int i, j = 0, valid_extensions = 0;
> -	u8 *edid, *new;
> -	struct edid *override;
> +	struct edid *edid, *new, *override;
>  
>  	override = drm_get_override_edid(connector);
>  	if (override)
>  		return override;
>  
> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>  	if (!edid)
>  		return NULL;
>  
>  	/* if there's no extensions or no connector, we're done */
> -	valid_extensions = edid[0x7e];
> +	valid_extensions = edid->extensions;
>  	if (valid_extensions == 0)
> -		return (struct edid *)edid;
> +		return edid;
>  
>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>  	if (!new)
>  		goto out;
>  	edid = new;
>  
> -	for (j = 1; j <= edid[0x7e]; j++) {
> -		u8 *block = edid + j * EDID_LENGTH;
> +	for (j = 1; j <= edid->extensions; j++) {
> +		void *block = edid + j;
>  
>  		for (i = 0; i < 4; i++) {
>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			valid_extensions--;
>  	}
>  
> -	if (valid_extensions != edid[0x7e]) {
> -		u8 *base;
> +	if (valid_extensions != edid->extensions) {
> +		struct edid *base;

This one points to extension blocks too so using 
struct edid doesn't seem entirely appropriate.

>  
> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>  
> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> -		edid[0x7e] = valid_extensions;
> +		edid->checksum += edid->extensions - valid_extensions;
> +		edid->extensions = valid_extensions;
>  
>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>  				    GFP_KERNEL);
> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			goto out;
>  
>  		base = new;
> -		for (i = 0; i <= edid[0x7e]; i++) {
> -			u8 *block = edid + i * EDID_LENGTH;
> +		for (i = 0; i <= edid->extensions; i++) {
> +			void *block = edid + i;

Hmm. This code seems very broken to me. We read each block
into its expected offset based on the original base block extension
count, but here we only iterate up to the new ext block count. So
if we had eg. a 4 block EDID where block 2 is busted, we set 
the new ext count to 2, copy over blocks 0 and 1, skip block 2,
and then terminate the loop. So instead of copying block 3 from
the orignal EDID into block 2 of the new EDID, we leave the
original garbage block 2 in place.

Also this memcpy() business seems entirely poinless in the sense
that we could just read each ext block into the final offset
directly AFAICS.

>  
>  			if (!drm_edid_block_valid(block, i, false, NULL))
>  				continue;
>  
>  			memcpy(base, block, EDID_LENGTH);
> -			base += EDID_LENGTH;
> +			base++;
>  		}
>  
>  		kfree(edid);
>  		edid = new;
>  	}
>  
> -	return (struct edid *)edid;
> +	return edid;
>  
>  out:
>  	kfree(edid);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 13:05     ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 13:05 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> Mixing u8 * and struct edid * is confusing, switch to the latter.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>  1 file changed, 15 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index d79b06f7f34c..0650b9217aa2 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  	void *data)
>  {
>  	int i, j = 0, valid_extensions = 0;
> -	u8 *edid, *new;
> -	struct edid *override;
> +	struct edid *edid, *new, *override;
>  
>  	override = drm_get_override_edid(connector);
>  	if (override)
>  		return override;
>  
> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>  	if (!edid)
>  		return NULL;
>  
>  	/* if there's no extensions or no connector, we're done */
> -	valid_extensions = edid[0x7e];
> +	valid_extensions = edid->extensions;
>  	if (valid_extensions == 0)
> -		return (struct edid *)edid;
> +		return edid;
>  
>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>  	if (!new)
>  		goto out;
>  	edid = new;
>  
> -	for (j = 1; j <= edid[0x7e]; j++) {
> -		u8 *block = edid + j * EDID_LENGTH;
> +	for (j = 1; j <= edid->extensions; j++) {
> +		void *block = edid + j;
>  
>  		for (i = 0; i < 4; i++) {
>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			valid_extensions--;
>  	}
>  
> -	if (valid_extensions != edid[0x7e]) {
> -		u8 *base;
> +	if (valid_extensions != edid->extensions) {
> +		struct edid *base;

This one points to extension blocks too so using 
struct edid doesn't seem entirely appropriate.

>  
> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>  
> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> -		edid[0x7e] = valid_extensions;
> +		edid->checksum += edid->extensions - valid_extensions;
> +		edid->extensions = valid_extensions;
>  
>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>  				    GFP_KERNEL);
> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			goto out;
>  
>  		base = new;
> -		for (i = 0; i <= edid[0x7e]; i++) {
> -			u8 *block = edid + i * EDID_LENGTH;
> +		for (i = 0; i <= edid->extensions; i++) {
> +			void *block = edid + i;

Hmm. This code seems very broken to me. We read each block
into its expected offset based on the original base block extension
count, but here we only iterate up to the new ext block count. So
if we had eg. a 4 block EDID where block 2 is busted, we set 
the new ext count to 2, copy over blocks 0 and 1, skip block 2,
and then terminate the loop. So instead of copying block 3 from
the orignal EDID into block 2 of the new EDID, we leave the
original garbage block 2 in place.

Also this memcpy() business seems entirely poinless in the sense
that we could just read each ext block into the final offset
directly AFAICS.

>  
>  			if (!drm_edid_block_valid(block, i, false, NULL))
>  				continue;
>  
>  			memcpy(base, block, EDID_LENGTH);
> -			base += EDID_LENGTH;
> +			base++;
>  		}
>  
>  		kfree(edid);
>  		edid = new;
>  	}
>  
> -	return (struct edid *)edid;
> +	return edid;
>  
>  out:
>  	kfree(edid);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 13:05     ` [Intel-gfx] " Ville Syrjälä
@ 2022-03-30 15:16       ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 15:16 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> Mixing u8 * and struct edid * is confusing, switch to the latter.
>> 
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>>  1 file changed, 15 insertions(+), 16 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index d79b06f7f34c..0650b9217aa2 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  	void *data)
>>  {
>>  	int i, j = 0, valid_extensions = 0;
>> -	u8 *edid, *new;
>> -	struct edid *override;
>> +	struct edid *edid, *new, *override;
>>  
>>  	override = drm_get_override_edid(connector);
>>  	if (override)
>>  		return override;
>>  
>> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
>> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>>  	if (!edid)
>>  		return NULL;
>>  
>>  	/* if there's no extensions or no connector, we're done */
>> -	valid_extensions = edid[0x7e];
>> +	valid_extensions = edid->extensions;
>>  	if (valid_extensions == 0)
>> -		return (struct edid *)edid;
>> +		return edid;
>>  
>>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>>  	if (!new)
>>  		goto out;
>>  	edid = new;
>>  
>> -	for (j = 1; j <= edid[0x7e]; j++) {
>> -		u8 *block = edid + j * EDID_LENGTH;
>> +	for (j = 1; j <= edid->extensions; j++) {
>> +		void *block = edid + j;
>>  
>>  		for (i = 0; i < 4; i++) {
>>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  			valid_extensions--;
>>  	}
>>  
>> -	if (valid_extensions != edid[0x7e]) {
>> -		u8 *base;
>> +	if (valid_extensions != edid->extensions) {
>> +		struct edid *base;
>
> This one points to extension blocks too so using 
> struct edid doesn't seem entirely appropriate.

So I've gone back and forth with this. I think I want to get rid of u8*
no matter what, because it always requires casting. I've used void* here
and there to allow mixed use, internally in drm_edid.c while
transitioning, and in public interfaces due to usage all over the place.

OTOH I don't much like arithmetics on void*. It's a gcc extension.

struct edid * is useful for e.g. ->checksum and arithmetics. In many
places I've named it struct edid *block to distinguish. We could have a
struct edid_block too, which could have ->tag and ->checksum members,
for example, but then it would require casting or a function for "safe"
typecasting.

I've also gone back and forth with the helpers for getting a pointer to
a block. For usage like this, kind of need both const and non-const
versions. And, with the plans I have for future, I'm not sure I want to
promote any EDID parsing outside of drm_edid.c, so maybe they should be
static.

Undecided. C is a bit clunky here.

>
>>  
>> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
>> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>>  
>> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
>> -		edid[0x7e] = valid_extensions;
>> +		edid->checksum += edid->extensions - valid_extensions;
>> +		edid->extensions = valid_extensions;
>>  
>>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>>  				    GFP_KERNEL);
>> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  			goto out;
>>  
>>  		base = new;
>> -		for (i = 0; i <= edid[0x7e]; i++) {
>> -			u8 *block = edid + i * EDID_LENGTH;
>> +		for (i = 0; i <= edid->extensions; i++) {
>> +			void *block = edid + i;
>
> Hmm. This code seems very broken to me. We read each block
> into its expected offset based on the original base block extension
> count, but here we only iterate up to the new ext block count. So
> if we had eg. a 4 block EDID where block 2 is busted, we set 
> the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> and then terminate the loop. So instead of copying block 3 from
> the orignal EDID into block 2 of the new EDID, we leave the
> original garbage block 2 in place.

Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
block filtering to a separate function", but I don't mention it
anywhere.

Looks like it's been broken for 5+ years since commit 14544d0937bf
("drm/edid: Only print the bad edid when aborting").

Which really makes you wonder about the usefulness of trying to "fix"
the EDID by skipping extension blocks. It was added in commit
0ea75e23356f ("DRM: ignore invalid EDID extensions").

> Also this memcpy() business seems entirely poinless in the sense
> that we could just read each ext block into the final offset
> directly AFAICS.

This is how it was before commit 14544d0937bf. I guess the point is if
we decide the EDID is garbage, we want to print the original EDID, once,
not something we've already changed. I also kind of like the idea of
hiding the broken EDID path magic in a separate function.


BR,
Jani.


>
>>  
>>  			if (!drm_edid_block_valid(block, i, false, NULL))
>>  				continue;
>>  
>>  			memcpy(base, block, EDID_LENGTH);
>> -			base += EDID_LENGTH;
>> +			base++;
>>  		}
>>  
>>  		kfree(edid);
>>  		edid = new;
>>  	}
>>  
>> -	return (struct edid *)edid;
>> +	return edid;
>>  
>>  out:
>>  	kfree(edid);
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 15:16       ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 15:16 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> Mixing u8 * and struct edid * is confusing, switch to the latter.
>> 
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>>  1 file changed, 15 insertions(+), 16 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index d79b06f7f34c..0650b9217aa2 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  	void *data)
>>  {
>>  	int i, j = 0, valid_extensions = 0;
>> -	u8 *edid, *new;
>> -	struct edid *override;
>> +	struct edid *edid, *new, *override;
>>  
>>  	override = drm_get_override_edid(connector);
>>  	if (override)
>>  		return override;
>>  
>> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
>> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>>  	if (!edid)
>>  		return NULL;
>>  
>>  	/* if there's no extensions or no connector, we're done */
>> -	valid_extensions = edid[0x7e];
>> +	valid_extensions = edid->extensions;
>>  	if (valid_extensions == 0)
>> -		return (struct edid *)edid;
>> +		return edid;
>>  
>>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>>  	if (!new)
>>  		goto out;
>>  	edid = new;
>>  
>> -	for (j = 1; j <= edid[0x7e]; j++) {
>> -		u8 *block = edid + j * EDID_LENGTH;
>> +	for (j = 1; j <= edid->extensions; j++) {
>> +		void *block = edid + j;
>>  
>>  		for (i = 0; i < 4; i++) {
>>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  			valid_extensions--;
>>  	}
>>  
>> -	if (valid_extensions != edid[0x7e]) {
>> -		u8 *base;
>> +	if (valid_extensions != edid->extensions) {
>> +		struct edid *base;
>
> This one points to extension blocks too so using 
> struct edid doesn't seem entirely appropriate.

So I've gone back and forth with this. I think I want to get rid of u8*
no matter what, because it always requires casting. I've used void* here
and there to allow mixed use, internally in drm_edid.c while
transitioning, and in public interfaces due to usage all over the place.

OTOH I don't much like arithmetics on void*. It's a gcc extension.

struct edid * is useful for e.g. ->checksum and arithmetics. In many
places I've named it struct edid *block to distinguish. We could have a
struct edid_block too, which could have ->tag and ->checksum members,
for example, but then it would require casting or a function for "safe"
typecasting.

I've also gone back and forth with the helpers for getting a pointer to
a block. For usage like this, kind of need both const and non-const
versions. And, with the plans I have for future, I'm not sure I want to
promote any EDID parsing outside of drm_edid.c, so maybe they should be
static.

Undecided. C is a bit clunky here.

>
>>  
>> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
>> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>>  
>> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
>> -		edid[0x7e] = valid_extensions;
>> +		edid->checksum += edid->extensions - valid_extensions;
>> +		edid->extensions = valid_extensions;
>>  
>>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>>  				    GFP_KERNEL);
>> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  			goto out;
>>  
>>  		base = new;
>> -		for (i = 0; i <= edid[0x7e]; i++) {
>> -			u8 *block = edid + i * EDID_LENGTH;
>> +		for (i = 0; i <= edid->extensions; i++) {
>> +			void *block = edid + i;
>
> Hmm. This code seems very broken to me. We read each block
> into its expected offset based on the original base block extension
> count, but here we only iterate up to the new ext block count. So
> if we had eg. a 4 block EDID where block 2 is busted, we set 
> the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> and then terminate the loop. So instead of copying block 3 from
> the orignal EDID into block 2 of the new EDID, we leave the
> original garbage block 2 in place.

Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
block filtering to a separate function", but I don't mention it
anywhere.

Looks like it's been broken for 5+ years since commit 14544d0937bf
("drm/edid: Only print the bad edid when aborting").

Which really makes you wonder about the usefulness of trying to "fix"
the EDID by skipping extension blocks. It was added in commit
0ea75e23356f ("DRM: ignore invalid EDID extensions").

> Also this memcpy() business seems entirely poinless in the sense
> that we could just read each ext block into the final offset
> directly AFAICS.

This is how it was before commit 14544d0937bf. I guess the point is if
we decide the EDID is garbage, we want to print the original EDID, once,
not something we've already changed. I also kind of like the idea of
hiding the broken EDID path magic in a separate function.


BR,
Jani.


>
>>  
>>  			if (!drm_edid_block_valid(block, i, false, NULL))
>>  				continue;
>>  
>>  			memcpy(base, block, EDID_LENGTH);
>> -			base += EDID_LENGTH;
>> +			base++;
>>  		}
>>  
>>  		kfree(edid);
>>  		edid = new;
>>  	}
>>  
>> -	return (struct edid *)edid;
>> +	return edid;
>>  
>>  out:
>>  	kfree(edid);
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 15:16       ` [Intel-gfx] " Jani Nikula
@ 2022-03-30 15:39         ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 15:39 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
> >> 
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
> >>  1 file changed, 15 insertions(+), 16 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> >> index d79b06f7f34c..0650b9217aa2 100644
> >> --- a/drivers/gpu/drm/drm_edid.c
> >> +++ b/drivers/gpu/drm/drm_edid.c
> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  	void *data)
> >>  {
> >>  	int i, j = 0, valid_extensions = 0;
> >> -	u8 *edid, *new;
> >> -	struct edid *override;
> >> +	struct edid *edid, *new, *override;
> >>  
> >>  	override = drm_get_override_edid(connector);
> >>  	if (override)
> >>  		return override;
> >>  
> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
> >>  	if (!edid)
> >>  		return NULL;
> >>  
> >>  	/* if there's no extensions or no connector, we're done */
> >> -	valid_extensions = edid[0x7e];
> >> +	valid_extensions = edid->extensions;
> >>  	if (valid_extensions == 0)
> >> -		return (struct edid *)edid;
> >> +		return edid;
> >>  
> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
> >>  	if (!new)
> >>  		goto out;
> >>  	edid = new;
> >>  
> >> -	for (j = 1; j <= edid[0x7e]; j++) {
> >> -		u8 *block = edid + j * EDID_LENGTH;
> >> +	for (j = 1; j <= edid->extensions; j++) {
> >> +		void *block = edid + j;
> >>  
> >>  		for (i = 0; i < 4; i++) {
> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  			valid_extensions--;
> >>  	}
> >>  
> >> -	if (valid_extensions != edid[0x7e]) {
> >> -		u8 *base;
> >> +	if (valid_extensions != edid->extensions) {
> >> +		struct edid *base;
> >
> > This one points to extension blocks too so using 
> > struct edid doesn't seem entirely appropriate.
> 
> So I've gone back and forth with this. I think I want to get rid of u8*
> no matter what, because it always requires casting. I've used void* here
> and there to allow mixed use, internally in drm_edid.c while
> transitioning, and in public interfaces due to usage all over the place.
> 
> OTOH I don't much like arithmetics on void*. It's a gcc extension.
> 
> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> places I've named it struct edid *block to distinguish. We could have a
> struct edid_block too, which could have ->tag and ->checksum members,
> for example, but then it would require casting or a function for "safe"
> typecasting.
> 
> I've also gone back and forth with the helpers for getting a pointer to
> a block. For usage like this, kind of need both const and non-const
> versions. And, with the plans I have for future, I'm not sure I want to
> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> static.
> 
> Undecided. C is a bit clunky here.
> 
> >
> >>  
> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
> >>  
> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> >> -		edid[0x7e] = valid_extensions;
> >> +		edid->checksum += edid->extensions - valid_extensions;
> >> +		edid->extensions = valid_extensions;
> >>  
> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
> >>  				    GFP_KERNEL);
> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  			goto out;
> >>  
> >>  		base = new;
> >> -		for (i = 0; i <= edid[0x7e]; i++) {
> >> -			u8 *block = edid + i * EDID_LENGTH;
> >> +		for (i = 0; i <= edid->extensions; i++) {
> >> +			void *block = edid + i;
> >
> > Hmm. This code seems very broken to me. We read each block
> > into its expected offset based on the original base block extension
> > count, but here we only iterate up to the new ext block count. So
> > if we had eg. a 4 block EDID where block 2 is busted, we set 
> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> > and then terminate the loop. So instead of copying block 3 from
> > the orignal EDID into block 2 of the new EDID, we leave the
> > original garbage block 2 in place.
> 
> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
> block filtering to a separate function", but I don't mention it
> anywhere.
> 
> Looks like it's been broken for 5+ years since commit 14544d0937bf
> ("drm/edid: Only print the bad edid when aborting").
> 
> Which really makes you wonder about the usefulness of trying to "fix"
> the EDID by skipping extension blocks. It was added in commit
> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
> 
> > Also this memcpy() business seems entirely poinless in the sense
> > that we could just read each ext block into the final offset
> > directly AFAICS.
> 
> This is how it was before commit 14544d0937bf.

Hmm. This is actually even a bit worse than I though since it
looks like we can leak uninitialized stuff from kmalloc_array().
I originally thought it was a krealloc()+memmove() but that is
not the case.

> I guess the point is if
> we decide the EDID is garbage, we want to print the original EDID, once,
> not something we've already changed. I also kind of like the idea of
> hiding the broken EDID path magic in a separate function.

I'm wondering we should just stop with this bad block filtering
entirely? Just let the block be all zeroes/crap if that is really
what we got from the sink. And we could still skip known broken
blocks during parsing to avoid getting too confused I guess.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 15:39         ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 15:39 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
> >> 
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
> >>  1 file changed, 15 insertions(+), 16 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> >> index d79b06f7f34c..0650b9217aa2 100644
> >> --- a/drivers/gpu/drm/drm_edid.c
> >> +++ b/drivers/gpu/drm/drm_edid.c
> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  	void *data)
> >>  {
> >>  	int i, j = 0, valid_extensions = 0;
> >> -	u8 *edid, *new;
> >> -	struct edid *override;
> >> +	struct edid *edid, *new, *override;
> >>  
> >>  	override = drm_get_override_edid(connector);
> >>  	if (override)
> >>  		return override;
> >>  
> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
> >>  	if (!edid)
> >>  		return NULL;
> >>  
> >>  	/* if there's no extensions or no connector, we're done */
> >> -	valid_extensions = edid[0x7e];
> >> +	valid_extensions = edid->extensions;
> >>  	if (valid_extensions == 0)
> >> -		return (struct edid *)edid;
> >> +		return edid;
> >>  
> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
> >>  	if (!new)
> >>  		goto out;
> >>  	edid = new;
> >>  
> >> -	for (j = 1; j <= edid[0x7e]; j++) {
> >> -		u8 *block = edid + j * EDID_LENGTH;
> >> +	for (j = 1; j <= edid->extensions; j++) {
> >> +		void *block = edid + j;
> >>  
> >>  		for (i = 0; i < 4; i++) {
> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  			valid_extensions--;
> >>  	}
> >>  
> >> -	if (valid_extensions != edid[0x7e]) {
> >> -		u8 *base;
> >> +	if (valid_extensions != edid->extensions) {
> >> +		struct edid *base;
> >
> > This one points to extension blocks too so using 
> > struct edid doesn't seem entirely appropriate.
> 
> So I've gone back and forth with this. I think I want to get rid of u8*
> no matter what, because it always requires casting. I've used void* here
> and there to allow mixed use, internally in drm_edid.c while
> transitioning, and in public interfaces due to usage all over the place.
> 
> OTOH I don't much like arithmetics on void*. It's a gcc extension.
> 
> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> places I've named it struct edid *block to distinguish. We could have a
> struct edid_block too, which could have ->tag and ->checksum members,
> for example, but then it would require casting or a function for "safe"
> typecasting.
> 
> I've also gone back and forth with the helpers for getting a pointer to
> a block. For usage like this, kind of need both const and non-const
> versions. And, with the plans I have for future, I'm not sure I want to
> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> static.
> 
> Undecided. C is a bit clunky here.
> 
> >
> >>  
> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
> >>  
> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> >> -		edid[0x7e] = valid_extensions;
> >> +		edid->checksum += edid->extensions - valid_extensions;
> >> +		edid->extensions = valid_extensions;
> >>  
> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
> >>  				    GFP_KERNEL);
> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >>  			goto out;
> >>  
> >>  		base = new;
> >> -		for (i = 0; i <= edid[0x7e]; i++) {
> >> -			u8 *block = edid + i * EDID_LENGTH;
> >> +		for (i = 0; i <= edid->extensions; i++) {
> >> +			void *block = edid + i;
> >
> > Hmm. This code seems very broken to me. We read each block
> > into its expected offset based on the original base block extension
> > count, but here we only iterate up to the new ext block count. So
> > if we had eg. a 4 block EDID where block 2 is busted, we set 
> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> > and then terminate the loop. So instead of copying block 3 from
> > the orignal EDID into block 2 of the new EDID, we leave the
> > original garbage block 2 in place.
> 
> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
> block filtering to a separate function", but I don't mention it
> anywhere.
> 
> Looks like it's been broken for 5+ years since commit 14544d0937bf
> ("drm/edid: Only print the bad edid when aborting").
> 
> Which really makes you wonder about the usefulness of trying to "fix"
> the EDID by skipping extension blocks. It was added in commit
> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
> 
> > Also this memcpy() business seems entirely poinless in the sense
> > that we could just read each ext block into the final offset
> > directly AFAICS.
> 
> This is how it was before commit 14544d0937bf.

Hmm. This is actually even a bit worse than I though since it
looks like we can leak uninitialized stuff from kmalloc_array().
I originally thought it was a krealloc()+memmove() but that is
not the case.

> I guess the point is if
> we decide the EDID is garbage, we want to print the original EDID, once,
> not something we've already changed. I also kind of like the idea of
> hiding the broken EDID path magic in a separate function.

I'm wondering we should just stop with this bad block filtering
entirely? Just let the block be all zeroes/crap if that is really
what we got from the sink. And we could still skip known broken
blocks during parsing to avoid getting too confused I guess.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 15:39         ` [Intel-gfx] " Ville Syrjälä
@ 2022-03-30 16:28           ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 16:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
>> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
>> >> 
>> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>> >>  1 file changed, 15 insertions(+), 16 deletions(-)
>> >> 
>> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> >> index d79b06f7f34c..0650b9217aa2 100644
>> >> --- a/drivers/gpu/drm/drm_edid.c
>> >> +++ b/drivers/gpu/drm/drm_edid.c
>> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  	void *data)
>> >>  {
>> >>  	int i, j = 0, valid_extensions = 0;
>> >> -	u8 *edid, *new;
>> >> -	struct edid *override;
>> >> +	struct edid *edid, *new, *override;
>> >>  
>> >>  	override = drm_get_override_edid(connector);
>> >>  	if (override)
>> >>  		return override;
>> >>  
>> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
>> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>> >>  	if (!edid)
>> >>  		return NULL;
>> >>  
>> >>  	/* if there's no extensions or no connector, we're done */
>> >> -	valid_extensions = edid[0x7e];
>> >> +	valid_extensions = edid->extensions;
>> >>  	if (valid_extensions == 0)
>> >> -		return (struct edid *)edid;
>> >> +		return edid;
>> >>  
>> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>> >>  	if (!new)
>> >>  		goto out;
>> >>  	edid = new;
>> >>  
>> >> -	for (j = 1; j <= edid[0x7e]; j++) {
>> >> -		u8 *block = edid + j * EDID_LENGTH;
>> >> +	for (j = 1; j <= edid->extensions; j++) {
>> >> +		void *block = edid + j;
>> >>  
>> >>  		for (i = 0; i < 4; i++) {
>> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  			valid_extensions--;
>> >>  	}
>> >>  
>> >> -	if (valid_extensions != edid[0x7e]) {
>> >> -		u8 *base;
>> >> +	if (valid_extensions != edid->extensions) {
>> >> +		struct edid *base;
>> >
>> > This one points to extension blocks too so using 
>> > struct edid doesn't seem entirely appropriate.
>> 
>> So I've gone back and forth with this. I think I want to get rid of u8*
>> no matter what, because it always requires casting. I've used void* here
>> and there to allow mixed use, internally in drm_edid.c while
>> transitioning, and in public interfaces due to usage all over the place.
>> 
>> OTOH I don't much like arithmetics on void*. It's a gcc extension.
>> 
>> struct edid * is useful for e.g. ->checksum and arithmetics. In many
>> places I've named it struct edid *block to distinguish. We could have a
>> struct edid_block too, which could have ->tag and ->checksum members,
>> for example, but then it would require casting or a function for "safe"
>> typecasting.
>> 
>> I've also gone back and forth with the helpers for getting a pointer to
>> a block. For usage like this, kind of need both const and non-const
>> versions. And, with the plans I have for future, I'm not sure I want to
>> promote any EDID parsing outside of drm_edid.c, so maybe they should be
>> static.
>> 
>> Undecided. C is a bit clunky here.
>> 
>> >
>> >>  
>> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
>> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>> >>  
>> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
>> >> -		edid[0x7e] = valid_extensions;
>> >> +		edid->checksum += edid->extensions - valid_extensions;
>> >> +		edid->extensions = valid_extensions;
>> >>  
>> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>> >>  				    GFP_KERNEL);
>> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  			goto out;
>> >>  
>> >>  		base = new;
>> >> -		for (i = 0; i <= edid[0x7e]; i++) {
>> >> -			u8 *block = edid + i * EDID_LENGTH;
>> >> +		for (i = 0; i <= edid->extensions; i++) {
>> >> +			void *block = edid + i;
>> >
>> > Hmm. This code seems very broken to me. We read each block
>> > into its expected offset based on the original base block extension
>> > count, but here we only iterate up to the new ext block count. So
>> > if we had eg. a 4 block EDID where block 2 is busted, we set 
>> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
>> > and then terminate the loop. So instead of copying block 3 from
>> > the orignal EDID into block 2 of the new EDID, we leave the
>> > original garbage block 2 in place.
>> 
>> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
>> block filtering to a separate function", but I don't mention it
>> anywhere.
>> 
>> Looks like it's been broken for 5+ years since commit 14544d0937bf
>> ("drm/edid: Only print the bad edid when aborting").
>> 
>> Which really makes you wonder about the usefulness of trying to "fix"
>> the EDID by skipping extension blocks. It was added in commit
>> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
>> 
>> > Also this memcpy() business seems entirely poinless in the sense
>> > that we could just read each ext block into the final offset
>> > directly AFAICS.
>> 
>> This is how it was before commit 14544d0937bf.
>
> Hmm. This is actually even a bit worse than I though since it
> looks like we can leak uninitialized stuff from kmalloc_array().
> I originally thought it was a krealloc()+memmove() but that is
> not the case.
>
>> I guess the point is if
>> we decide the EDID is garbage, we want to print the original EDID, once,
>> not something we've already changed. I also kind of like the idea of
>> hiding the broken EDID path magic in a separate function.
>
> I'm wondering we should just stop with this bad block filtering
> entirely? Just let the block be all zeroes/crap if that is really
> what we got from the sink. And we could still skip known broken
> blocks during parsing to avoid getting too confused I guess.

I think by far the most common extension count must be 1. Especially
with older displays I think anything beyond 256 bytes is virtually
non-existent. Agreed?

With that, going from 1 to 0 extensions, it actually works by
coincidence, no leaks, no uninitialized stuff. (Looks like maybe any
scenario where it's the last N extensions that are invalid works just
fine, and it's the broken extensions in the middle that make this go
haywire.)

So maybe it's not so scary after all. I could fix that bit first, and
then proceed with the rest of the series. I'm a bit hesitant to make big
functional changes now, like stopping the filtering entirely, because
it's not just drm_edid.c parsing the returned EDIDs, parsing is all over
the place.

And on that note, my idea (also for HF-EEODB, my end goal) is to move
towards an opaque struct drm_edid, which is 1) generated and parsed
exclusively within drm_edid.c, nowhere else, 2) always valid to be
passed to drm_edid.c (i.e. always be able to handle what we've
generated, whatever that is). If you want the benefits of HF-EEODB or
new DisplayID 2.0 features or whatever, you switch your driver to struct
drm_edid. But you can keep rolling with the legacy struct edid crap ad
infinitum.

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 16:28           ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 16:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
>> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
>> >> 
>> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
>> >>  1 file changed, 15 insertions(+), 16 deletions(-)
>> >> 
>> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> >> index d79b06f7f34c..0650b9217aa2 100644
>> >> --- a/drivers/gpu/drm/drm_edid.c
>> >> +++ b/drivers/gpu/drm/drm_edid.c
>> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  	void *data)
>> >>  {
>> >>  	int i, j = 0, valid_extensions = 0;
>> >> -	u8 *edid, *new;
>> >> -	struct edid *override;
>> >> +	struct edid *edid, *new, *override;
>> >>  
>> >>  	override = drm_get_override_edid(connector);
>> >>  	if (override)
>> >>  		return override;
>> >>  
>> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
>> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
>> >>  	if (!edid)
>> >>  		return NULL;
>> >>  
>> >>  	/* if there's no extensions or no connector, we're done */
>> >> -	valid_extensions = edid[0x7e];
>> >> +	valid_extensions = edid->extensions;
>> >>  	if (valid_extensions == 0)
>> >> -		return (struct edid *)edid;
>> >> +		return edid;
>> >>  
>> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
>> >>  	if (!new)
>> >>  		goto out;
>> >>  	edid = new;
>> >>  
>> >> -	for (j = 1; j <= edid[0x7e]; j++) {
>> >> -		u8 *block = edid + j * EDID_LENGTH;
>> >> +	for (j = 1; j <= edid->extensions; j++) {
>> >> +		void *block = edid + j;
>> >>  
>> >>  		for (i = 0; i < 4; i++) {
>> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  			valid_extensions--;
>> >>  	}
>> >>  
>> >> -	if (valid_extensions != edid[0x7e]) {
>> >> -		u8 *base;
>> >> +	if (valid_extensions != edid->extensions) {
>> >> +		struct edid *base;
>> >
>> > This one points to extension blocks too so using 
>> > struct edid doesn't seem entirely appropriate.
>> 
>> So I've gone back and forth with this. I think I want to get rid of u8*
>> no matter what, because it always requires casting. I've used void* here
>> and there to allow mixed use, internally in drm_edid.c while
>> transitioning, and in public interfaces due to usage all over the place.
>> 
>> OTOH I don't much like arithmetics on void*. It's a gcc extension.
>> 
>> struct edid * is useful for e.g. ->checksum and arithmetics. In many
>> places I've named it struct edid *block to distinguish. We could have a
>> struct edid_block too, which could have ->tag and ->checksum members,
>> for example, but then it would require casting or a function for "safe"
>> typecasting.
>> 
>> I've also gone back and forth with the helpers for getting a pointer to
>> a block. For usage like this, kind of need both const and non-const
>> versions. And, with the plans I have for future, I'm not sure I want to
>> promote any EDID parsing outside of drm_edid.c, so maybe they should be
>> static.
>> 
>> Undecided. C is a bit clunky here.
>> 
>> >
>> >>  
>> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
>> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>> >>  
>> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
>> >> -		edid[0x7e] = valid_extensions;
>> >> +		edid->checksum += edid->extensions - valid_extensions;
>> >> +		edid->extensions = valid_extensions;
>> >>  
>> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
>> >>  				    GFP_KERNEL);
>> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>> >>  			goto out;
>> >>  
>> >>  		base = new;
>> >> -		for (i = 0; i <= edid[0x7e]; i++) {
>> >> -			u8 *block = edid + i * EDID_LENGTH;
>> >> +		for (i = 0; i <= edid->extensions; i++) {
>> >> +			void *block = edid + i;
>> >
>> > Hmm. This code seems very broken to me. We read each block
>> > into its expected offset based on the original base block extension
>> > count, but here we only iterate up to the new ext block count. So
>> > if we had eg. a 4 block EDID where block 2 is busted, we set 
>> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
>> > and then terminate the loop. So instead of copying block 3 from
>> > the orignal EDID into block 2 of the new EDID, we leave the
>> > original garbage block 2 in place.
>> 
>> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
>> block filtering to a separate function", but I don't mention it
>> anywhere.
>> 
>> Looks like it's been broken for 5+ years since commit 14544d0937bf
>> ("drm/edid: Only print the bad edid when aborting").
>> 
>> Which really makes you wonder about the usefulness of trying to "fix"
>> the EDID by skipping extension blocks. It was added in commit
>> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
>> 
>> > Also this memcpy() business seems entirely poinless in the sense
>> > that we could just read each ext block into the final offset
>> > directly AFAICS.
>> 
>> This is how it was before commit 14544d0937bf.
>
> Hmm. This is actually even a bit worse than I though since it
> looks like we can leak uninitialized stuff from kmalloc_array().
> I originally thought it was a krealloc()+memmove() but that is
> not the case.
>
>> I guess the point is if
>> we decide the EDID is garbage, we want to print the original EDID, once,
>> not something we've already changed. I also kind of like the idea of
>> hiding the broken EDID path magic in a separate function.
>
> I'm wondering we should just stop with this bad block filtering
> entirely? Just let the block be all zeroes/crap if that is really
> what we got from the sink. And we could still skip known broken
> blocks during parsing to avoid getting too confused I guess.

I think by far the most common extension count must be 1. Especially
with older displays I think anything beyond 256 bytes is virtually
non-existent. Agreed?

With that, going from 1 to 0 extensions, it actually works by
coincidence, no leaks, no uninitialized stuff. (Looks like maybe any
scenario where it's the last N extensions that are invalid works just
fine, and it's the broken extensions in the middle that make this go
haywire.)

So maybe it's not so scary after all. I could fix that bit first, and
then proceed with the rest of the series. I'm a bit hesitant to make big
functional changes now, like stopping the filtering entirely, because
it's not just drm_edid.c parsing the returned EDIDs, parsing is all over
the place.

And on that note, my idea (also for HF-EEODB, my end goal) is to move
towards an opaque struct drm_edid, which is 1) generated and parsed
exclusively within drm_edid.c, nowhere else, 2) always valid to be
passed to drm_edid.c (i.e. always be able to handle what we've
generated, whatever that is). If you want the benefits of HF-EEODB or
new DisplayID 2.0 features or whatever, you switch your driver to struct
drm_edid. But you can keep rolling with the legacy struct edid crap ad
infinitum.

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 16:28           ` [Intel-gfx] " Jani Nikula
@ 2022-03-30 16:50             ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 16:50 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Mar 30, 2022 at 07:28:56PM +0300, Jani Nikula wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
> >> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> >> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> >> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
> >> >> 
> >> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> >> ---
> >> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
> >> >>  1 file changed, 15 insertions(+), 16 deletions(-)
> >> >> 
> >> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> >> >> index d79b06f7f34c..0650b9217aa2 100644
> >> >> --- a/drivers/gpu/drm/drm_edid.c
> >> >> +++ b/drivers/gpu/drm/drm_edid.c
> >> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  	void *data)
> >> >>  {
> >> >>  	int i, j = 0, valid_extensions = 0;
> >> >> -	u8 *edid, *new;
> >> >> -	struct edid *override;
> >> >> +	struct edid *edid, *new, *override;
> >> >>  
> >> >>  	override = drm_get_override_edid(connector);
> >> >>  	if (override)
> >> >>  		return override;
> >> >>  
> >> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> >>  	if (!edid)
> >> >>  		return NULL;
> >> >>  
> >> >>  	/* if there's no extensions or no connector, we're done */
> >> >> -	valid_extensions = edid[0x7e];
> >> >> +	valid_extensions = edid->extensions;
> >> >>  	if (valid_extensions == 0)
> >> >> -		return (struct edid *)edid;
> >> >> +		return edid;
> >> >>  
> >> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
> >> >>  	if (!new)
> >> >>  		goto out;
> >> >>  	edid = new;
> >> >>  
> >> >> -	for (j = 1; j <= edid[0x7e]; j++) {
> >> >> -		u8 *block = edid + j * EDID_LENGTH;
> >> >> +	for (j = 1; j <= edid->extensions; j++) {
> >> >> +		void *block = edid + j;
> >> >>  
> >> >>  		for (i = 0; i < 4; i++) {
> >> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> >> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  			valid_extensions--;
> >> >>  	}
> >> >>  
> >> >> -	if (valid_extensions != edid[0x7e]) {
> >> >> -		u8 *base;
> >> >> +	if (valid_extensions != edid->extensions) {
> >> >> +		struct edid *base;
> >> >
> >> > This one points to extension blocks too so using 
> >> > struct edid doesn't seem entirely appropriate.
> >> 
> >> So I've gone back and forth with this. I think I want to get rid of u8*
> >> no matter what, because it always requires casting. I've used void* here
> >> and there to allow mixed use, internally in drm_edid.c while
> >> transitioning, and in public interfaces due to usage all over the place.
> >> 
> >> OTOH I don't much like arithmetics on void*. It's a gcc extension.
> >> 
> >> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> >> places I've named it struct edid *block to distinguish. We could have a
> >> struct edid_block too, which could have ->tag and ->checksum members,
> >> for example, but then it would require casting or a function for "safe"
> >> typecasting.
> >> 
> >> I've also gone back and forth with the helpers for getting a pointer to
> >> a block. For usage like this, kind of need both const and non-const
> >> versions. And, with the plans I have for future, I'm not sure I want to
> >> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> >> static.
> >> 
> >> Undecided. C is a bit clunky here.
> >> 
> >> >
> >> >>  
> >> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> >> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
> >> >>  
> >> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> >> >> -		edid[0x7e] = valid_extensions;
> >> >> +		edid->checksum += edid->extensions - valid_extensions;
> >> >> +		edid->extensions = valid_extensions;
> >> >>  
> >> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
> >> >>  				    GFP_KERNEL);
> >> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  			goto out;
> >> >>  
> >> >>  		base = new;
> >> >> -		for (i = 0; i <= edid[0x7e]; i++) {
> >> >> -			u8 *block = edid + i * EDID_LENGTH;
> >> >> +		for (i = 0; i <= edid->extensions; i++) {
> >> >> +			void *block = edid + i;
> >> >
> >> > Hmm. This code seems very broken to me. We read each block
> >> > into its expected offset based on the original base block extension
> >> > count, but here we only iterate up to the new ext block count. So
> >> > if we had eg. a 4 block EDID where block 2 is busted, we set 
> >> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> >> > and then terminate the loop. So instead of copying block 3 from
> >> > the orignal EDID into block 2 of the new EDID, we leave the
> >> > original garbage block 2 in place.
> >> 
> >> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
> >> block filtering to a separate function", but I don't mention it
> >> anywhere.
> >> 
> >> Looks like it's been broken for 5+ years since commit 14544d0937bf
> >> ("drm/edid: Only print the bad edid when aborting").
> >> 
> >> Which really makes you wonder about the usefulness of trying to "fix"
> >> the EDID by skipping extension blocks. It was added in commit
> >> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
> >> 
> >> > Also this memcpy() business seems entirely poinless in the sense
> >> > that we could just read each ext block into the final offset
> >> > directly AFAICS.
> >> 
> >> This is how it was before commit 14544d0937bf.
> >
> > Hmm. This is actually even a bit worse than I though since it
> > looks like we can leak uninitialized stuff from kmalloc_array().
> > I originally thought it was a krealloc()+memmove() but that is
> > not the case.
> >
> >> I guess the point is if
> >> we decide the EDID is garbage, we want to print the original EDID, once,
> >> not something we've already changed. I also kind of like the idea of
> >> hiding the broken EDID path magic in a separate function.
> >
> > I'm wondering we should just stop with this bad block filtering
> > entirely? Just let the block be all zeroes/crap if that is really
> > what we got from the sink. And we could still skip known broken
> > blocks during parsing to avoid getting too confused I guess.
> 
> I think by far the most common extension count must be 1. Especially
> with older displays I think anything beyond 256 bytes is virtually
> non-existent. Agreed?

More than one extension block is certainly pretty rare.

edid-decode has a few with 3 (base + CTA + DispID), and my
edid.tv dump seems to have two with 4 blocks (one has base +
CTA + 2 DispID blocks, the other has base + block map +
2 CTA blocks).

> 
> With that, going from 1 to 0 extensions, it actually works by
> coincidence, no leaks, no uninitialized stuff. (Looks like maybe any
> scenario where it's the last N extensions that are invalid works just
> fine, and it's the broken extensions in the middle that make this go
> haywire.)
> 
> So maybe it's not so scary after all. I could fix that bit first, and
> then proceed with the rest of the series.

I'd fix this up front so we don't end having to backport the whole
thing if/when some security scan gizmo stumbles on this.

> I'm a bit hesitant to make big
> functional changes now, like stopping the filtering entirely, because
> it's not just drm_edid.c parsing the returned EDIDs, parsing is all over
> the place.

Sure. Just threw it out there as a future idea.

> And on that note, my idea (also for HF-EEODB, my end goal) is to move
> towards an opaque struct drm_edid, which is 1) generated and parsed
> exclusively within drm_edid.c, nowhere else, 2) always valid to be
> passed to drm_edid.c (i.e. always be able to handle what we've
> generated, whatever that is). If you want the benefits of HF-EEODB or
> new DisplayID 2.0 features or whatever, you switch your driver to struct
> drm_edid. But you can keep rolling with the legacy struct edid crap ad
> infinitum.

Hopefully we can shame enough people to fix their stuff eventually :P
But yeah, trying to fix it all right now is a bit much.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 16:50             ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-30 16:50 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Wed, Mar 30, 2022 at 07:28:56PM +0300, Jani Nikula wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Wed, Mar 30, 2022 at 06:16:17PM +0300, Jani Nikula wrote:
> >> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> >> > On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
> >> >> Mixing u8 * and struct edid * is confusing, switch to the latter.
> >> >> 
> >> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> >> ---
> >> >>  drivers/gpu/drm/drm_edid.c | 31 +++++++++++++++----------------
> >> >>  1 file changed, 15 insertions(+), 16 deletions(-)
> >> >> 
> >> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> >> >> index d79b06f7f34c..0650b9217aa2 100644
> >> >> --- a/drivers/gpu/drm/drm_edid.c
> >> >> +++ b/drivers/gpu/drm/drm_edid.c
> >> >> @@ -1991,29 +1991,28 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  	void *data)
> >> >>  {
> >> >>  	int i, j = 0, valid_extensions = 0;
> >> >> -	u8 *edid, *new;
> >> >> -	struct edid *override;
> >> >> +	struct edid *edid, *new, *override;
> >> >>  
> >> >>  	override = drm_get_override_edid(connector);
> >> >>  	if (override)
> >> >>  		return override;
> >> >>  
> >> >> -	edid = (u8 *)drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> >> +	edid = drm_do_get_edid_base_block(connector, get_edid_block, data);
> >> >>  	if (!edid)
> >> >>  		return NULL;
> >> >>  
> >> >>  	/* if there's no extensions or no connector, we're done */
> >> >> -	valid_extensions = edid[0x7e];
> >> >> +	valid_extensions = edid->extensions;
> >> >>  	if (valid_extensions == 0)
> >> >> -		return (struct edid *)edid;
> >> >> +		return edid;
> >> >>  
> >> >>  	new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
> >> >>  	if (!new)
> >> >>  		goto out;
> >> >>  	edid = new;
> >> >>  
> >> >> -	for (j = 1; j <= edid[0x7e]; j++) {
> >> >> -		u8 *block = edid + j * EDID_LENGTH;
> >> >> +	for (j = 1; j <= edid->extensions; j++) {
> >> >> +		void *block = edid + j;
> >> >>  
> >> >>  		for (i = 0; i < 4; i++) {
> >> >>  			if (get_edid_block(data, block, j, EDID_LENGTH))
> >> >> @@ -2026,13 +2025,13 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  			valid_extensions--;
> >> >>  	}
> >> >>  
> >> >> -	if (valid_extensions != edid[0x7e]) {
> >> >> -		u8 *base;
> >> >> +	if (valid_extensions != edid->extensions) {
> >> >> +		struct edid *base;
> >> >
> >> > This one points to extension blocks too so using 
> >> > struct edid doesn't seem entirely appropriate.
> >> 
> >> So I've gone back and forth with this. I think I want to get rid of u8*
> >> no matter what, because it always requires casting. I've used void* here
> >> and there to allow mixed use, internally in drm_edid.c while
> >> transitioning, and in public interfaces due to usage all over the place.
> >> 
> >> OTOH I don't much like arithmetics on void*. It's a gcc extension.
> >> 
> >> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> >> places I've named it struct edid *block to distinguish. We could have a
> >> struct edid_block too, which could have ->tag and ->checksum members,
> >> for example, but then it would require casting or a function for "safe"
> >> typecasting.
> >> 
> >> I've also gone back and forth with the helpers for getting a pointer to
> >> a block. For usage like this, kind of need both const and non-const
> >> versions. And, with the plans I have for future, I'm not sure I want to
> >> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> >> static.
> >> 
> >> Undecided. C is a bit clunky here.
> >> 
> >> >
> >> >>  
> >> >> -		connector_bad_edid(connector, edid, edid[0x7e] + 1);
> >> >> +		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
> >> >>  
> >> >> -		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
> >> >> -		edid[0x7e] = valid_extensions;
> >> >> +		edid->checksum += edid->extensions - valid_extensions;
> >> >> +		edid->extensions = valid_extensions;
> >> >>  
> >> >>  		new = kmalloc_array(valid_extensions + 1, EDID_LENGTH,
> >> >>  				    GFP_KERNEL);
> >> >> @@ -2040,21 +2039,21 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
> >> >>  			goto out;
> >> >>  
> >> >>  		base = new;
> >> >> -		for (i = 0; i <= edid[0x7e]; i++) {
> >> >> -			u8 *block = edid + i * EDID_LENGTH;
> >> >> +		for (i = 0; i <= edid->extensions; i++) {
> >> >> +			void *block = edid + i;
> >> >
> >> > Hmm. This code seems very broken to me. We read each block
> >> > into its expected offset based on the original base block extension
> >> > count, but here we only iterate up to the new ext block count. So
> >> > if we had eg. a 4 block EDID where block 2 is busted, we set 
> >> > the new ext count to 2, copy over blocks 0 and 1, skip block 2,
> >> > and then terminate the loop. So instead of copying block 3 from
> >> > the orignal EDID into block 2 of the new EDID, we leave the
> >> > original garbage block 2 in place.
> >> 
> >> Ugh. I end up fixing this in the series, in "drm/edid: split out invalid
> >> block filtering to a separate function", but I don't mention it
> >> anywhere.
> >> 
> >> Looks like it's been broken for 5+ years since commit 14544d0937bf
> >> ("drm/edid: Only print the bad edid when aborting").
> >> 
> >> Which really makes you wonder about the usefulness of trying to "fix"
> >> the EDID by skipping extension blocks. It was added in commit
> >> 0ea75e23356f ("DRM: ignore invalid EDID extensions").
> >> 
> >> > Also this memcpy() business seems entirely poinless in the sense
> >> > that we could just read each ext block into the final offset
> >> > directly AFAICS.
> >> 
> >> This is how it was before commit 14544d0937bf.
> >
> > Hmm. This is actually even a bit worse than I though since it
> > looks like we can leak uninitialized stuff from kmalloc_array().
> > I originally thought it was a krealloc()+memmove() but that is
> > not the case.
> >
> >> I guess the point is if
> >> we decide the EDID is garbage, we want to print the original EDID, once,
> >> not something we've already changed. I also kind of like the idea of
> >> hiding the broken EDID path magic in a separate function.
> >
> > I'm wondering we should just stop with this bad block filtering
> > entirely? Just let the block be all zeroes/crap if that is really
> > what we got from the sink. And we could still skip known broken
> > blocks during parsing to avoid getting too confused I guess.
> 
> I think by far the most common extension count must be 1. Especially
> with older displays I think anything beyond 256 bytes is virtually
> non-existent. Agreed?

More than one extension block is certainly pretty rare.

edid-decode has a few with 3 (base + CTA + DispID), and my
edid.tv dump seems to have two with 4 blocks (one has base +
CTA + 2 DispID blocks, the other has base + block map +
2 CTA blocks).

> 
> With that, going from 1 to 0 extensions, it actually works by
> coincidence, no leaks, no uninitialized stuff. (Looks like maybe any
> scenario where it's the last N extensions that are invalid works just
> fine, and it's the broken extensions in the middle that make this go
> haywire.)
> 
> So maybe it's not so scary after all. I could fix that bit first, and
> then proceed with the rest of the series.

I'd fix this up front so we don't end having to backport the whole
thing if/when some security scan gizmo stumbles on this.

> I'm a bit hesitant to make big
> functional changes now, like stopping the filtering entirely, because
> it's not just drm_edid.c parsing the returned EDIDs, parsing is all over
> the place.

Sure. Just threw it out there as a future idea.

> And on that note, my idea (also for HF-EEODB, my end goal) is to move
> towards an opaque struct drm_edid, which is 1) generated and parsed
> exclusively within drm_edid.c, nowhere else, 2) always valid to be
> passed to drm_edid.c (i.e. always be able to handle what we've
> generated, whatever that is). If you want the benefits of HF-EEODB or
> new DisplayID 2.0 features or whatever, you switch your driver to struct
> drm_edid. But you can keep rolling with the legacy struct edid crap ad
> infinitum.

Hopefully we can shame enough people to fix their stuff eventually :P
But yeah, trying to fix it all right now is a bit much.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 16:50             ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2022-03-30 17:09             ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 17:09 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> I'd fix this up front so we don't end having to backport the whole
> thing if/when some security scan gizmo stumbles on this.

Sent separately [1]. I'll rebase this series on top once that gets
merged, but the conflict is trivial so I think the first round of review
could go on here in parallel.


BR,
Jani.


[1] https://patchwork.freedesktop.org/patch/msgid/20220330170426.349248-1-jani.nikula@intel.com


-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 15:16       ` [Intel-gfx] " Jani Nikula
@ 2022-03-30 21:01         ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 21:01 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Jani Nikula <jani.nikula@intel.com> wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> This one points to extension blocks too so using 
>> struct edid doesn't seem entirely appropriate.
>
> So I've gone back and forth with this. I think I want to get rid of u8*
> no matter what, because it always requires casting. I've used void* here
> and there to allow mixed use, internally in drm_edid.c while
> transitioning, and in public interfaces due to usage all over the place.
>
> OTOH I don't much like arithmetics on void*. It's a gcc extension.
>
> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> places I've named it struct edid *block to distinguish. We could have a
> struct edid_block too, which could have ->tag and ->checksum members,
> for example, but then it would require casting or a function for "safe"
> typecasting.
>
> I've also gone back and forth with the helpers for getting a pointer to
> a block. For usage like this, kind of need both const and non-const
> versions. And, with the plans I have for future, I'm not sure I want to
> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> static.
>
> Undecided. C is a bit clunky here.

Hmm. I wonder how a flexible array member would pan out.

struct edid_extension {
	u8 tag;
        u8 revision;
        u8 data[EDID_LENGTH - 3];
        u8 checksum;
} __packed;

struct edid {
	/* existing stuff*/
        struct edid_extension extensions[];
} __packed;


BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-30 21:01         ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-30 21:01 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Jani Nikula <jani.nikula@intel.com> wrote:
> On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> This one points to extension blocks too so using 
>> struct edid doesn't seem entirely appropriate.
>
> So I've gone back and forth with this. I think I want to get rid of u8*
> no matter what, because it always requires casting. I've used void* here
> and there to allow mixed use, internally in drm_edid.c while
> transitioning, and in public interfaces due to usage all over the place.
>
> OTOH I don't much like arithmetics on void*. It's a gcc extension.
>
> struct edid * is useful for e.g. ->checksum and arithmetics. In many
> places I've named it struct edid *block to distinguish. We could have a
> struct edid_block too, which could have ->tag and ->checksum members,
> for example, but then it would require casting or a function for "safe"
> typecasting.
>
> I've also gone back and forth with the helpers for getting a pointer to
> a block. For usage like this, kind of need both const and non-const
> versions. And, with the plans I have for future, I'm not sure I want to
> promote any EDID parsing outside of drm_edid.c, so maybe they should be
> static.
>
> Undecided. C is a bit clunky here.

Hmm. I wonder how a flexible array member would pan out.

struct edid_extension {
	u8 tag;
        u8 revision;
        u8 data[EDID_LENGTH - 3];
        u8 checksum;
} __packed;

struct edid {
	/* existing stuff*/
        struct edid_extension extensions[];
} __packed;


BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
  2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
@ 2022-03-31 14:54     ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:54 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:14PM +0300, Jani Nikula wrote:
> Add edid_block_check() that only checks the EDID block validity, without
> any actions. Turns out it's simple and crystal clear.
> 
> Rewrite drm_edid_block_valid() around it, keeping all the functionality
> fairly closely the same, warts and all. Turns out it's incredibly
> complicated for a function you'd expect to be simple, with all the
> fixing and printing and special casing. (Maybe we'll want to simplify it
> in the future.)
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
>  1 file changed, 88 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 481643751d10..04eb6949c9c8 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
>  }
>  EXPORT_SYMBOL(drm_edid_are_equal);
>  
> +enum edid_block_status {
> +	EDID_BLOCK_OK = 0,
> +	EDID_BLOCK_NULL,
> +	EDID_BLOCK_HEADER_CORRUPT,
> +	EDID_BLOCK_HEADER_REPAIR,
> +	EDID_BLOCK_HEADER_FIXED,
> +	EDID_BLOCK_CHECKSUM,
> +	EDID_BLOCK_VERSION,
> +};
> +
> +static enum edid_block_status edid_block_check(const void *_block, bool base)

s/base/is_base_block/ or something?

> +{
> +	const struct edid *block = _block;
> +
> +	if (!block)
> +		return EDID_BLOCK_NULL;
> +
> +	if (base) {
> +		int score = drm_edid_header_is_valid(block);
> +
> +		if (score < clamp(edid_fixup, 6, 8))

That should clamp to 0-8?

Might be nicer to just define a .set() op for the modparam
and check it there, but that's clearly material for a separate patch.

> +			return EDID_BLOCK_HEADER_CORRUPT;
> +
> +		if (score < 8)
> +			return EDID_BLOCK_HEADER_REPAIR;
> +	}
> +
> +	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
> +		return EDID_BLOCK_CHECKSUM;
> +
> +	if (base) {
> +		if (block->version != 1)
> +			return EDID_BLOCK_VERSION;
> +	}
> +
> +	return EDID_BLOCK_OK;
> +}
> +
> +static bool edid_block_status_valid(enum edid_block_status status, int tag)
> +{
> +	return status == EDID_BLOCK_OK ||
> +		status == EDID_BLOCK_HEADER_FIXED ||
> +		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
> +}
> +
>  /**
>   * drm_edid_block_valid - Sanity check the EDID block (base or extension)
>   * @raw_edid: pointer to raw EDID block
> - * @block: type of block to validate (0 for base, extension otherwise)
> + * @block_num: type of block to validate (0 for base, extension otherwise)
>   * @print_bad_edid: if true, dump bad EDID blocks to the console
>   * @edid_corrupt: if true, the header or checksum is invalid
>   *
> @@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
>   *
>   * Return: True if the block is valid, false otherwise.
>   */
> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
> +bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
>  			  bool *edid_corrupt)
>  {
> -	u8 csum;
> -	struct edid *edid = (struct edid *)raw_edid;
> +	struct edid *block = (struct edid *)_block;
> +	enum edid_block_status status;
> +	bool base = block_num == 0;
> +	bool valid;
>  
> -	if (WARN_ON(!raw_edid))
> +	if (WARN_ON(!block))
>  		return false;
>  
> -	if (edid_fixup > 8 || edid_fixup < 0)
> -		edid_fixup = 6;
> -
> -	if (block == 0) {
> -		int score = drm_edid_header_is_valid(raw_edid);
> +	status = edid_block_check(block, base);
> +	if (status == EDID_BLOCK_HEADER_REPAIR) {
> +		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
> +		edid_header_fix(block);
>  
> -		if (score == 8) {
> -			if (edid_corrupt)
> -				*edid_corrupt = false;
> -		} else if (score >= edid_fixup) {
> -			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
> -			 * The corrupt flag needs to be set here otherwise, the
> -			 * fix-up code here will correct the problem, the
> -			 * checksum is correct and the test fails
> -			 */
> -			if (edid_corrupt)
> -				*edid_corrupt = true;
> -			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
> -			edid_header_fix(raw_edid);
> -		} else {
> -			if (edid_corrupt)
> -				*edid_corrupt = true;
> -			goto bad;
> -		}
> +		/* Retry with fixed header, update status if that worked. */
> +		status = edid_block_check(block, base);
> +		if (status == EDID_BLOCK_OK)
> +			status = EDID_BLOCK_HEADER_FIXED;
>  	}
>  
> -	csum = edid_block_compute_checksum(raw_edid);
> -	if (csum != edid_block_get_checksum(raw_edid)) {
> -		if (edid_corrupt)
> +	if (edid_corrupt) {
> +		/*
> +		 * Unknown major version isn't corrupt but we can't use it. Only
> +		 * the base block can reset edid_corrupt to false.
> +		 */
> +		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
> +			*edid_corrupt = false;
> +		else if (status != EDID_BLOCK_OK)
>  			*edid_corrupt = true;
> -
> -		/* allow CEA to slide through, switches mangle this */
> -		if (edid_block_tag(raw_edid) == CEA_EXT) {
> -			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
> -			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
> -		} else {
> -			if (print_bad_edid)
> -				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
> -
> -			goto bad;
> -		}
>  	}
>  
> -	/* per-block-type checks */
> -	switch (edid_block_tag(raw_edid)) {
> -	case 0: /* base */
> -		if (edid->version != 1) {
> -			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
> -			goto bad;
> +	/* Determine whether we can use this block with this status. */
> +	valid = edid_block_status_valid(status, edid_block_tag(block));
> +
> +	/* Some fairly random status printouts. */
> +	if (status == EDID_BLOCK_CHECKSUM) {
> +		if (valid) {
> +			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
> +				  edid_block_compute_checksum(block));
> +			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
> +		} else if (print_bad_edid) {
> +			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
> +				 edid_block_compute_checksum(block));
>  		}
> -
> -		if (edid->revision > 4)
> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");

This debug message seems to disappear. Intentional?

> -		break;
> -
> -	default:
> -		break;
> +	} else if (status == EDID_BLOCK_VERSION) {
> +		DRM_NOTE("EDID has major version %d, instead of 1\n",
> +			 block->version);
>  	}
>  
> -	return true;
> -
> -bad:
> -	if (print_bad_edid) {
> -		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
> +	if (!valid && print_bad_edid) {
> +		if (edid_is_zero(block, EDID_LENGTH)) {
>  			pr_notice("EDID block is all zeroes\n");
>  		} else {
>  			pr_notice("Raw EDID:\n");
>  			print_hex_dump(KERN_NOTICE,
>  				       " \t", DUMP_PREFIX_NONE, 16, 1,
> -				       raw_edid, EDID_LENGTH, false);
> +				       block, EDID_LENGTH, false);
>  		}
>  	}
> -	return false;
> +
> +	return valid;
>  }
>  EXPORT_SYMBOL(drm_edid_block_valid);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
@ 2022-03-31 14:54     ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:54 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:14PM +0300, Jani Nikula wrote:
> Add edid_block_check() that only checks the EDID block validity, without
> any actions. Turns out it's simple and crystal clear.
> 
> Rewrite drm_edid_block_valid() around it, keeping all the functionality
> fairly closely the same, warts and all. Turns out it's incredibly
> complicated for a function you'd expect to be simple, with all the
> fixing and printing and special casing. (Maybe we'll want to simplify it
> in the future.)
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
>  1 file changed, 88 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 481643751d10..04eb6949c9c8 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
>  }
>  EXPORT_SYMBOL(drm_edid_are_equal);
>  
> +enum edid_block_status {
> +	EDID_BLOCK_OK = 0,
> +	EDID_BLOCK_NULL,
> +	EDID_BLOCK_HEADER_CORRUPT,
> +	EDID_BLOCK_HEADER_REPAIR,
> +	EDID_BLOCK_HEADER_FIXED,
> +	EDID_BLOCK_CHECKSUM,
> +	EDID_BLOCK_VERSION,
> +};
> +
> +static enum edid_block_status edid_block_check(const void *_block, bool base)

s/base/is_base_block/ or something?

> +{
> +	const struct edid *block = _block;
> +
> +	if (!block)
> +		return EDID_BLOCK_NULL;
> +
> +	if (base) {
> +		int score = drm_edid_header_is_valid(block);
> +
> +		if (score < clamp(edid_fixup, 6, 8))

That should clamp to 0-8?

Might be nicer to just define a .set() op for the modparam
and check it there, but that's clearly material for a separate patch.

> +			return EDID_BLOCK_HEADER_CORRUPT;
> +
> +		if (score < 8)
> +			return EDID_BLOCK_HEADER_REPAIR;
> +	}
> +
> +	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
> +		return EDID_BLOCK_CHECKSUM;
> +
> +	if (base) {
> +		if (block->version != 1)
> +			return EDID_BLOCK_VERSION;
> +	}
> +
> +	return EDID_BLOCK_OK;
> +}
> +
> +static bool edid_block_status_valid(enum edid_block_status status, int tag)
> +{
> +	return status == EDID_BLOCK_OK ||
> +		status == EDID_BLOCK_HEADER_FIXED ||
> +		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
> +}
> +
>  /**
>   * drm_edid_block_valid - Sanity check the EDID block (base or extension)
>   * @raw_edid: pointer to raw EDID block
> - * @block: type of block to validate (0 for base, extension otherwise)
> + * @block_num: type of block to validate (0 for base, extension otherwise)
>   * @print_bad_edid: if true, dump bad EDID blocks to the console
>   * @edid_corrupt: if true, the header or checksum is invalid
>   *
> @@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
>   *
>   * Return: True if the block is valid, false otherwise.
>   */
> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
> +bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
>  			  bool *edid_corrupt)
>  {
> -	u8 csum;
> -	struct edid *edid = (struct edid *)raw_edid;
> +	struct edid *block = (struct edid *)_block;
> +	enum edid_block_status status;
> +	bool base = block_num == 0;
> +	bool valid;
>  
> -	if (WARN_ON(!raw_edid))
> +	if (WARN_ON(!block))
>  		return false;
>  
> -	if (edid_fixup > 8 || edid_fixup < 0)
> -		edid_fixup = 6;
> -
> -	if (block == 0) {
> -		int score = drm_edid_header_is_valid(raw_edid);
> +	status = edid_block_check(block, base);
> +	if (status == EDID_BLOCK_HEADER_REPAIR) {
> +		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
> +		edid_header_fix(block);
>  
> -		if (score == 8) {
> -			if (edid_corrupt)
> -				*edid_corrupt = false;
> -		} else if (score >= edid_fixup) {
> -			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
> -			 * The corrupt flag needs to be set here otherwise, the
> -			 * fix-up code here will correct the problem, the
> -			 * checksum is correct and the test fails
> -			 */
> -			if (edid_corrupt)
> -				*edid_corrupt = true;
> -			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
> -			edid_header_fix(raw_edid);
> -		} else {
> -			if (edid_corrupt)
> -				*edid_corrupt = true;
> -			goto bad;
> -		}
> +		/* Retry with fixed header, update status if that worked. */
> +		status = edid_block_check(block, base);
> +		if (status == EDID_BLOCK_OK)
> +			status = EDID_BLOCK_HEADER_FIXED;
>  	}
>  
> -	csum = edid_block_compute_checksum(raw_edid);
> -	if (csum != edid_block_get_checksum(raw_edid)) {
> -		if (edid_corrupt)
> +	if (edid_corrupt) {
> +		/*
> +		 * Unknown major version isn't corrupt but we can't use it. Only
> +		 * the base block can reset edid_corrupt to false.
> +		 */
> +		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
> +			*edid_corrupt = false;
> +		else if (status != EDID_BLOCK_OK)
>  			*edid_corrupt = true;
> -
> -		/* allow CEA to slide through, switches mangle this */
> -		if (edid_block_tag(raw_edid) == CEA_EXT) {
> -			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
> -			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
> -		} else {
> -			if (print_bad_edid)
> -				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
> -
> -			goto bad;
> -		}
>  	}
>  
> -	/* per-block-type checks */
> -	switch (edid_block_tag(raw_edid)) {
> -	case 0: /* base */
> -		if (edid->version != 1) {
> -			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
> -			goto bad;
> +	/* Determine whether we can use this block with this status. */
> +	valid = edid_block_status_valid(status, edid_block_tag(block));
> +
> +	/* Some fairly random status printouts. */
> +	if (status == EDID_BLOCK_CHECKSUM) {
> +		if (valid) {
> +			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
> +				  edid_block_compute_checksum(block));
> +			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
> +		} else if (print_bad_edid) {
> +			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
> +				 edid_block_compute_checksum(block));
>  		}
> -
> -		if (edid->revision > 4)
> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");

This debug message seems to disappear. Intentional?

> -		break;
> -
> -	default:
> -		break;
> +	} else if (status == EDID_BLOCK_VERSION) {
> +		DRM_NOTE("EDID has major version %d, instead of 1\n",
> +			 block->version);
>  	}
>  
> -	return true;
> -
> -bad:
> -	if (print_bad_edid) {
> -		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
> +	if (!valid && print_bad_edid) {
> +		if (edid_is_zero(block, EDID_LENGTH)) {
>  			pr_notice("EDID block is all zeroes\n");
>  		} else {
>  			pr_notice("Raw EDID:\n");
>  			print_hex_dump(KERN_NOTICE,
>  				       " \t", DUMP_PREFIX_NONE, 16, 1,
> -				       raw_edid, EDID_LENGTH, false);
> +				       block, EDID_LENGTH, false);
>  		}
>  	}
> -	return false;
> +
> +	return valid;
>  }
>  EXPORT_SYMBOL(drm_edid_block_valid);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 08/12] drm/edid: use a better variable name for EDID block read retries
  2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
@ 2022-03-31 14:55     ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:55 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:15PM +0300, Jani Nikula wrote:
> Just i is a bit terse, clarify what it's about.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 04eb6949c9c8..235d3cde2e97 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1971,25 +1971,25 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
>  	int *null_edid_counter = connector ? &connector->null_edid_counter : NULL;
>  	bool *edid_corrupt = connector ? &connector->edid_corrupt : NULL;
>  	void *edid;
> -	int i;
> +	int try;
>  
>  	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
>  	if (edid == NULL)
>  		return NULL;
>  
>  	/* base block fetch */
> -	for (i = 0; i < 4; i++) {
> +	for (try = 0; try < 4; try++) {
>  		if (get_edid_block(data, edid, 0, EDID_LENGTH))
>  			goto out;
>  		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
>  			break;
> -		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
> +		if (try == 0 && edid_is_zero(edid, EDID_LENGTH)) {
>  			if (null_edid_counter)
>  				(*null_edid_counter)++;
>  			goto carp;
>  		}
>  	}
> -	if (i == 4)
> +	if (try == 4)
>  		goto carp;
>  
>  	return edid;
> @@ -2027,7 +2027,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			      size_t len),
>  	void *data)
>  {
> -	int i, j = 0, valid_extensions = 0;
> +	int j, valid_extensions = 0;
>  	struct edid *edid, *new, *override;
>  
>  	override = drm_get_override_edid(connector);
> @@ -2050,20 +2050,22 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  
>  	for (j = 1; j <= edid->extensions; j++) {
>  		void *block = edid + j;
> +		int try;
>  
> -		for (i = 0; i < 4; i++) {
> +		for (try = 0; try < 4; try++) {
>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>  				goto out;
>  			if (drm_edid_block_valid(block, j, false, NULL))
>  				break;
>  		}
>  
> -		if (i == 4)
> +		if (try == 4)
>  			valid_extensions--;
>  	}
>  
>  	if (valid_extensions != edid->extensions) {
>  		struct edid *base;
> +		int i;
>  
>  		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 08/12] drm/edid: use a better variable name for EDID block read retries
@ 2022-03-31 14:55     ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:55 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:15PM +0300, Jani Nikula wrote:
> Just i is a bit terse, clarify what it's about.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/drm_edid.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 04eb6949c9c8..235d3cde2e97 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1971,25 +1971,25 @@ static struct edid *drm_do_get_edid_base_block(struct drm_connector *connector,
>  	int *null_edid_counter = connector ? &connector->null_edid_counter : NULL;
>  	bool *edid_corrupt = connector ? &connector->edid_corrupt : NULL;
>  	void *edid;
> -	int i;
> +	int try;
>  
>  	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
>  	if (edid == NULL)
>  		return NULL;
>  
>  	/* base block fetch */
> -	for (i = 0; i < 4; i++) {
> +	for (try = 0; try < 4; try++) {
>  		if (get_edid_block(data, edid, 0, EDID_LENGTH))
>  			goto out;
>  		if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
>  			break;
> -		if (i == 0 && edid_is_zero(edid, EDID_LENGTH)) {
> +		if (try == 0 && edid_is_zero(edid, EDID_LENGTH)) {
>  			if (null_edid_counter)
>  				(*null_edid_counter)++;
>  			goto carp;
>  		}
>  	}
> -	if (i == 4)
> +	if (try == 4)
>  		goto carp;
>  
>  	return edid;
> @@ -2027,7 +2027,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  			      size_t len),
>  	void *data)
>  {
> -	int i, j = 0, valid_extensions = 0;
> +	int j, valid_extensions = 0;
>  	struct edid *edid, *new, *override;
>  
>  	override = drm_get_override_edid(connector);
> @@ -2050,20 +2050,22 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  
>  	for (j = 1; j <= edid->extensions; j++) {
>  		void *block = edid + j;
> +		int try;
>  
> -		for (i = 0; i < 4; i++) {
> +		for (try = 0; try < 4; try++) {
>  			if (get_edid_block(data, block, j, EDID_LENGTH))
>  				goto out;
>  			if (drm_edid_block_valid(block, j, false, NULL))
>  				break;
>  		}
>  
> -		if (i == 4)
> +		if (try == 4)
>  			valid_extensions--;
>  	}
>  
>  	if (valid_extensions != edid->extensions) {
>  		struct edid *base;
> +		int i;
>  
>  		connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1);
>  
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 12/12] drm/edid: reduce magic when updating the EDID block checksum
  2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
@ 2022-03-31 14:59     ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:59 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:19PM +0300, Jani Nikula wrote:
> The code modifying the EDID block should not need to do tricks to fix
> the checksum. We have a function for computing the checksum, use it.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index d0a76781ed19..d2dfab28b5b7 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1840,8 +1840,8 @@ static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
>  			memcpy(base++, block, EDID_LENGTH);
>  	}
>  
> -	new->checksum += new->extensions - valid_extensions;
>  	new->extensions = valid_extensions;
> +	new->checksum = edid_block_compute_checksum(new);

Seems to happen after we've validated the base block so this won't
accidentally fix up an already bad checksum.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>
>  out:
>  	kfree(edid);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 12/12] drm/edid: reduce magic when updating the EDID block checksum
@ 2022-03-31 14:59     ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 14:59 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:19PM +0300, Jani Nikula wrote:
> The code modifying the EDID block should not need to do tricks to fix
> the checksum. We have a function for computing the checksum, use it.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index d0a76781ed19..d2dfab28b5b7 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1840,8 +1840,8 @@ static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
>  			memcpy(base++, block, EDID_LENGTH);
>  	}
>  
> -	new->checksum += new->extensions - valid_extensions;
>  	new->extensions = valid_extensions;
> +	new->checksum = edid_block_compute_checksum(new);

Seems to happen after we've validated the base block so this won't
accidentally fix up an already bad checksum.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>
>  out:
>  	kfree(edid);
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
  2022-03-31 14:54     ` [Intel-gfx] " Ville Syrjälä
@ 2022-03-31 15:54       ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 15:54 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:14PM +0300, Jani Nikula wrote:
>> Add edid_block_check() that only checks the EDID block validity, without
>> any actions. Turns out it's simple and crystal clear.
>> 
>> Rewrite drm_edid_block_valid() around it, keeping all the functionality
>> fairly closely the same, warts and all. Turns out it's incredibly
>> complicated for a function you'd expect to be simple, with all the
>> fixing and printing and special casing. (Maybe we'll want to simplify it
>> in the future.)
>> 
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
>>  1 file changed, 88 insertions(+), 62 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 481643751d10..04eb6949c9c8 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
>>  }
>>  EXPORT_SYMBOL(drm_edid_are_equal);
>>  
>> +enum edid_block_status {
>> +	EDID_BLOCK_OK = 0,
>> +	EDID_BLOCK_NULL,
>> +	EDID_BLOCK_HEADER_CORRUPT,
>> +	EDID_BLOCK_HEADER_REPAIR,
>> +	EDID_BLOCK_HEADER_FIXED,
>> +	EDID_BLOCK_CHECKSUM,
>> +	EDID_BLOCK_VERSION,
>> +};
>> +
>> +static enum edid_block_status edid_block_check(const void *_block, bool base)
>
> s/base/is_base_block/ or something?

Okay.

>
>> +{
>> +	const struct edid *block = _block;
>> +
>> +	if (!block)
>> +		return EDID_BLOCK_NULL;
>> +
>> +	if (base) {
>> +		int score = drm_edid_header_is_valid(block);
>> +
>> +		if (score < clamp(edid_fixup, 6, 8))
>
> That should clamp to 0-8?

Indeed, thanks!

> Might be nicer to just define a .set() op for the modparam
> and check it there, but that's clearly material for a separate patch.

Yes.

BR,
Jani.

>
>> +			return EDID_BLOCK_HEADER_CORRUPT;
>> +
>> +		if (score < 8)
>> +			return EDID_BLOCK_HEADER_REPAIR;
>> +	}
>> +
>> +	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
>> +		return EDID_BLOCK_CHECKSUM;
>> +
>> +	if (base) {
>> +		if (block->version != 1)
>> +			return EDID_BLOCK_VERSION;
>> +	}
>> +
>> +	return EDID_BLOCK_OK;
>> +}
>> +
>> +static bool edid_block_status_valid(enum edid_block_status status, int tag)
>> +{
>> +	return status == EDID_BLOCK_OK ||
>> +		status == EDID_BLOCK_HEADER_FIXED ||
>> +		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
>> +}
>> +
>>  /**
>>   * drm_edid_block_valid - Sanity check the EDID block (base or extension)
>>   * @raw_edid: pointer to raw EDID block
>> - * @block: type of block to validate (0 for base, extension otherwise)
>> + * @block_num: type of block to validate (0 for base, extension otherwise)
>>   * @print_bad_edid: if true, dump bad EDID blocks to the console
>>   * @edid_corrupt: if true, the header or checksum is invalid
>>   *
>> @@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
>>   *
>>   * Return: True if the block is valid, false otherwise.
>>   */
>> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
>> +bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
>>  			  bool *edid_corrupt)
>>  {
>> -	u8 csum;
>> -	struct edid *edid = (struct edid *)raw_edid;
>> +	struct edid *block = (struct edid *)_block;
>> +	enum edid_block_status status;
>> +	bool base = block_num == 0;
>> +	bool valid;
>>  
>> -	if (WARN_ON(!raw_edid))
>> +	if (WARN_ON(!block))
>>  		return false;
>>  
>> -	if (edid_fixup > 8 || edid_fixup < 0)
>> -		edid_fixup = 6;
>> -
>> -	if (block == 0) {
>> -		int score = drm_edid_header_is_valid(raw_edid);
>> +	status = edid_block_check(block, base);
>> +	if (status == EDID_BLOCK_HEADER_REPAIR) {
>> +		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
>> +		edid_header_fix(block);
>>  
>> -		if (score == 8) {
>> -			if (edid_corrupt)
>> -				*edid_corrupt = false;
>> -		} else if (score >= edid_fixup) {
>> -			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
>> -			 * The corrupt flag needs to be set here otherwise, the
>> -			 * fix-up code here will correct the problem, the
>> -			 * checksum is correct and the test fails
>> -			 */
>> -			if (edid_corrupt)
>> -				*edid_corrupt = true;
>> -			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
>> -			edid_header_fix(raw_edid);
>> -		} else {
>> -			if (edid_corrupt)
>> -				*edid_corrupt = true;
>> -			goto bad;
>> -		}
>> +		/* Retry with fixed header, update status if that worked. */
>> +		status = edid_block_check(block, base);
>> +		if (status == EDID_BLOCK_OK)
>> +			status = EDID_BLOCK_HEADER_FIXED;
>>  	}
>>  
>> -	csum = edid_block_compute_checksum(raw_edid);
>> -	if (csum != edid_block_get_checksum(raw_edid)) {
>> -		if (edid_corrupt)
>> +	if (edid_corrupt) {
>> +		/*
>> +		 * Unknown major version isn't corrupt but we can't use it. Only
>> +		 * the base block can reset edid_corrupt to false.
>> +		 */
>> +		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
>> +			*edid_corrupt = false;
>> +		else if (status != EDID_BLOCK_OK)
>>  			*edid_corrupt = true;
>> -
>> -		/* allow CEA to slide through, switches mangle this */
>> -		if (edid_block_tag(raw_edid) == CEA_EXT) {
>> -			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
>> -			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
>> -		} else {
>> -			if (print_bad_edid)
>> -				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
>> -
>> -			goto bad;
>> -		}
>>  	}
>>  
>> -	/* per-block-type checks */
>> -	switch (edid_block_tag(raw_edid)) {
>> -	case 0: /* base */
>> -		if (edid->version != 1) {
>> -			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
>> -			goto bad;
>> +	/* Determine whether we can use this block with this status. */
>> +	valid = edid_block_status_valid(status, edid_block_tag(block));
>> +
>> +	/* Some fairly random status printouts. */
>> +	if (status == EDID_BLOCK_CHECKSUM) {
>> +		if (valid) {
>> +			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
>> +				  edid_block_compute_checksum(block));
>> +			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
>> +		} else if (print_bad_edid) {
>> +			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
>> +				 edid_block_compute_checksum(block));
>>  		}
>> -
>> -		if (edid->revision > 4)
>> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
>
> This debug message seems to disappear. Intentional?
>
>> -		break;
>> -
>> -	default:
>> -		break;
>> +	} else if (status == EDID_BLOCK_VERSION) {
>> +		DRM_NOTE("EDID has major version %d, instead of 1\n",
>> +			 block->version);
>>  	}
>>  
>> -	return true;
>> -
>> -bad:
>> -	if (print_bad_edid) {
>> -		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
>> +	if (!valid && print_bad_edid) {
>> +		if (edid_is_zero(block, EDID_LENGTH)) {
>>  			pr_notice("EDID block is all zeroes\n");
>>  		} else {
>>  			pr_notice("Raw EDID:\n");
>>  			print_hex_dump(KERN_NOTICE,
>>  				       " \t", DUMP_PREFIX_NONE, 16, 1,
>> -				       raw_edid, EDID_LENGTH, false);
>> +				       block, EDID_LENGTH, false);
>>  		}
>>  	}
>> -	return false;
>> +
>> +	return valid;
>>  }
>>  EXPORT_SYMBOL(drm_edid_block_valid);
>>  
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
@ 2022-03-31 15:54       ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 15:54 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:14PM +0300, Jani Nikula wrote:
>> Add edid_block_check() that only checks the EDID block validity, without
>> any actions. Turns out it's simple and crystal clear.
>> 
>> Rewrite drm_edid_block_valid() around it, keeping all the functionality
>> fairly closely the same, warts and all. Turns out it's incredibly
>> complicated for a function you'd expect to be simple, with all the
>> fixing and printing and special casing. (Maybe we'll want to simplify it
>> in the future.)
>> 
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/drm_edid.c | 150 ++++++++++++++++++++++---------------
>>  1 file changed, 88 insertions(+), 62 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 481643751d10..04eb6949c9c8 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1668,10 +1668,55 @@ bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
>>  }
>>  EXPORT_SYMBOL(drm_edid_are_equal);
>>  
>> +enum edid_block_status {
>> +	EDID_BLOCK_OK = 0,
>> +	EDID_BLOCK_NULL,
>> +	EDID_BLOCK_HEADER_CORRUPT,
>> +	EDID_BLOCK_HEADER_REPAIR,
>> +	EDID_BLOCK_HEADER_FIXED,
>> +	EDID_BLOCK_CHECKSUM,
>> +	EDID_BLOCK_VERSION,
>> +};
>> +
>> +static enum edid_block_status edid_block_check(const void *_block, bool base)
>
> s/base/is_base_block/ or something?

Okay.

>
>> +{
>> +	const struct edid *block = _block;
>> +
>> +	if (!block)
>> +		return EDID_BLOCK_NULL;
>> +
>> +	if (base) {
>> +		int score = drm_edid_header_is_valid(block);
>> +
>> +		if (score < clamp(edid_fixup, 6, 8))
>
> That should clamp to 0-8?

Indeed, thanks!

> Might be nicer to just define a .set() op for the modparam
> and check it there, but that's clearly material for a separate patch.

Yes.

BR,
Jani.

>
>> +			return EDID_BLOCK_HEADER_CORRUPT;
>> +
>> +		if (score < 8)
>> +			return EDID_BLOCK_HEADER_REPAIR;
>> +	}
>> +
>> +	if (edid_block_compute_checksum(block) != edid_block_get_checksum(block))
>> +		return EDID_BLOCK_CHECKSUM;
>> +
>> +	if (base) {
>> +		if (block->version != 1)
>> +			return EDID_BLOCK_VERSION;
>> +	}
>> +
>> +	return EDID_BLOCK_OK;
>> +}
>> +
>> +static bool edid_block_status_valid(enum edid_block_status status, int tag)
>> +{
>> +	return status == EDID_BLOCK_OK ||
>> +		status == EDID_BLOCK_HEADER_FIXED ||
>> +		(status == EDID_BLOCK_CHECKSUM && tag == CEA_EXT);
>> +}
>> +
>>  /**
>>   * drm_edid_block_valid - Sanity check the EDID block (base or extension)
>>   * @raw_edid: pointer to raw EDID block
>> - * @block: type of block to validate (0 for base, extension otherwise)
>> + * @block_num: type of block to validate (0 for base, extension otherwise)
>>   * @print_bad_edid: if true, dump bad EDID blocks to the console
>>   * @edid_corrupt: if true, the header or checksum is invalid
>>   *
>> @@ -1680,88 +1725,69 @@ EXPORT_SYMBOL(drm_edid_are_equal);
>>   *
>>   * Return: True if the block is valid, false otherwise.
>>   */
>> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
>> +bool drm_edid_block_valid(u8 *_block, int block_num, bool print_bad_edid,
>>  			  bool *edid_corrupt)
>>  {
>> -	u8 csum;
>> -	struct edid *edid = (struct edid *)raw_edid;
>> +	struct edid *block = (struct edid *)_block;
>> +	enum edid_block_status status;
>> +	bool base = block_num == 0;
>> +	bool valid;
>>  
>> -	if (WARN_ON(!raw_edid))
>> +	if (WARN_ON(!block))
>>  		return false;
>>  
>> -	if (edid_fixup > 8 || edid_fixup < 0)
>> -		edid_fixup = 6;
>> -
>> -	if (block == 0) {
>> -		int score = drm_edid_header_is_valid(raw_edid);
>> +	status = edid_block_check(block, base);
>> +	if (status == EDID_BLOCK_HEADER_REPAIR) {
>> +		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
>> +		edid_header_fix(block);
>>  
>> -		if (score == 8) {
>> -			if (edid_corrupt)
>> -				*edid_corrupt = false;
>> -		} else if (score >= edid_fixup) {
>> -			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
>> -			 * The corrupt flag needs to be set here otherwise, the
>> -			 * fix-up code here will correct the problem, the
>> -			 * checksum is correct and the test fails
>> -			 */
>> -			if (edid_corrupt)
>> -				*edid_corrupt = true;
>> -			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
>> -			edid_header_fix(raw_edid);
>> -		} else {
>> -			if (edid_corrupt)
>> -				*edid_corrupt = true;
>> -			goto bad;
>> -		}
>> +		/* Retry with fixed header, update status if that worked. */
>> +		status = edid_block_check(block, base);
>> +		if (status == EDID_BLOCK_OK)
>> +			status = EDID_BLOCK_HEADER_FIXED;
>>  	}
>>  
>> -	csum = edid_block_compute_checksum(raw_edid);
>> -	if (csum != edid_block_get_checksum(raw_edid)) {
>> -		if (edid_corrupt)
>> +	if (edid_corrupt) {
>> +		/*
>> +		 * Unknown major version isn't corrupt but we can't use it. Only
>> +		 * the base block can reset edid_corrupt to false.
>> +		 */
>> +		if (base && (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION))
>> +			*edid_corrupt = false;
>> +		else if (status != EDID_BLOCK_OK)
>>  			*edid_corrupt = true;
>> -
>> -		/* allow CEA to slide through, switches mangle this */
>> -		if (edid_block_tag(raw_edid) == CEA_EXT) {
>> -			DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum);
>> -			DRM_DEBUG("Assuming a KVM switch modified the CEA block but left the original checksum\n");
>> -		} else {
>> -			if (print_bad_edid)
>> -				DRM_NOTE("EDID checksum is invalid, remainder is %d\n", csum);
>> -
>> -			goto bad;
>> -		}
>>  	}
>>  
>> -	/* per-block-type checks */
>> -	switch (edid_block_tag(raw_edid)) {
>> -	case 0: /* base */
>> -		if (edid->version != 1) {
>> -			DRM_NOTE("EDID has major version %d, instead of 1\n", edid->version);
>> -			goto bad;
>> +	/* Determine whether we can use this block with this status. */
>> +	valid = edid_block_status_valid(status, edid_block_tag(block));
>> +
>> +	/* Some fairly random status printouts. */
>> +	if (status == EDID_BLOCK_CHECKSUM) {
>> +		if (valid) {
>> +			DRM_DEBUG("EDID block checksum is invalid, remainder is %d\n",
>> +				  edid_block_compute_checksum(block));
>> +			DRM_DEBUG("Assuming a KVM switch modified the block but left the original checksum\n");
>> +		} else if (print_bad_edid) {
>> +			DRM_NOTE("EDID block checksum is invalid, remainder is %d\n",
>> +				 edid_block_compute_checksum(block));
>>  		}
>> -
>> -		if (edid->revision > 4)
>> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
>
> This debug message seems to disappear. Intentional?
>
>> -		break;
>> -
>> -	default:
>> -		break;
>> +	} else if (status == EDID_BLOCK_VERSION) {
>> +		DRM_NOTE("EDID has major version %d, instead of 1\n",
>> +			 block->version);
>>  	}
>>  
>> -	return true;
>> -
>> -bad:
>> -	if (print_bad_edid) {
>> -		if (edid_is_zero(raw_edid, EDID_LENGTH)) {
>> +	if (!valid && print_bad_edid) {
>> +		if (edid_is_zero(block, EDID_LENGTH)) {
>>  			pr_notice("EDID block is all zeroes\n");
>>  		} else {
>>  			pr_notice("Raw EDID:\n");
>>  			print_hex_dump(KERN_NOTICE,
>>  				       " \t", DUMP_PREFIX_NONE, 16, 1,
>> -				       raw_edid, EDID_LENGTH, false);
>> +				       block, EDID_LENGTH, false);
>>  		}
>>  	}
>> -	return false;
>> +
>> +	return valid;
>>  }
>>  EXPORT_SYMBOL(drm_edid_block_valid);
>>  
>> -- 
>> 2.30.2

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
  2022-03-31 14:54     ` [Intel-gfx] " Ville Syrjälä
@ 2022-03-31 16:49       ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 16:49 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> -
>> -		if (edid->revision > 4)
>> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
>
> This debug message seems to disappear. Intentional?

Intentional, but failed to mention it in the commit message.

Do we want to keep it? With my new approach, it basically means another
valid return value that's distinct from just ok.


BR,
Jani.



-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
@ 2022-03-31 16:49       ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 16:49 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>> -
>> -		if (edid->revision > 4)
>> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
>
> This debug message seems to disappear. Intentional?

Intentional, but failed to mention it in the commit message.

Do we want to keep it? With my new approach, it basically means another
valid return value that's distinct from just ok.


BR,
Jani.



-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
  2022-03-31 16:49       ` [Intel-gfx] " Jani Nikula
@ 2022-03-31 16:58         ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 16:58 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Thu, Mar 31, 2022 at 07:49:10PM +0300, Jani Nikula wrote:
> On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> >> -
> >> -		if (edid->revision > 4)
> >> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
> >
> > This debug message seems to disappear. Intentional?
> 
> Intentional, but failed to mention it in the commit message.
> 
> Do we want to keep it? With my new approach, it basically means another
> valid return value that's distinct from just ok.

Seems pretty pointless to me. Especially with DisplayID on the
scene it seems rather unlikely that there would ever be EDID 1.5+.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts
@ 2022-03-31 16:58         ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 16:58 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Thu, Mar 31, 2022 at 07:49:10PM +0300, Jani Nikula wrote:
> On Thu, 31 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> >> -
> >> -		if (edid->revision > 4)
> >> -			DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
> >
> > This debug message seems to disappear. Intentional?
> 
> Intentional, but failed to mention it in the commit message.
> 
> Do we want to keep it? With my new approach, it basically means another
> valid return value that's distinct from just ok.

Seems pretty pointless to me. Especially with DisplayID on the
scene it seems rather unlikely that there would ever be EDID 1.5+.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 00/12] drm/edid: cleanup and refactoring around validity checks
  2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
@ 2022-03-31 17:07   ` Ville Syrjälä
  -1 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 17:07 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, Emil Velikov, dri-devel

On Tue, Mar 29, 2022 at 09:42:07PM +0300, Jani Nikula wrote:
> Another day, another batch of EDID code refactoring.
> 
> Mostly the goal was to simplify drm_do_get_edid(), but trying to extract
> a const function for checking a single block validity lead me down a
> rabbit hole...
> 
> BR,
> Jani.
> 
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> 
> Jani Nikula (12):
>   drm/edid: use struct edid * in drm_do_get_edid()
>   drm/edid: clean up EDID block checksum functions
>   drm/edid: add edid_block_tag() helper to get the EDID extension tag
>   drm/edid: make drm_edid_header_is_valid() accept void pointer
>   drm/edid: clean up edid_is_zero()
>   drm/edid: split out edid_header_fix()
>   drm/edid: split drm_edid_block_valid() to check and act parts
>   drm/edid: use a better variable name for EDID block read retries
>   drm/edid: simplify block check when filtering invalid blocks
>   drm/edid: split out invalid block filtering to a separate function
>   drm/edid: track invalid blocks in drm_do_get_edid()
>   drm/edid: reduce magic when updating the EDID block checksum

With the few bugs I spotted fixed the series is
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
>  drivers/gpu/drm/drm_edid.c | 293 +++++++++++++++++++++----------------
>  include/drm/drm_edid.h     |   2 +-
>  2 files changed, 171 insertions(+), 124 deletions(-)
> 
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 00/12] drm/edid: cleanup and refactoring around validity checks
@ 2022-03-31 17:07   ` Ville Syrjälä
  0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2022-03-31 17:07 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx, dri-devel

On Tue, Mar 29, 2022 at 09:42:07PM +0300, Jani Nikula wrote:
> Another day, another batch of EDID code refactoring.
> 
> Mostly the goal was to simplify drm_do_get_edid(), but trying to extract
> a const function for checking a single block validity lead me down a
> rabbit hole...
> 
> BR,
> Jani.
> 
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> 
> Jani Nikula (12):
>   drm/edid: use struct edid * in drm_do_get_edid()
>   drm/edid: clean up EDID block checksum functions
>   drm/edid: add edid_block_tag() helper to get the EDID extension tag
>   drm/edid: make drm_edid_header_is_valid() accept void pointer
>   drm/edid: clean up edid_is_zero()
>   drm/edid: split out edid_header_fix()
>   drm/edid: split drm_edid_block_valid() to check and act parts
>   drm/edid: use a better variable name for EDID block read retries
>   drm/edid: simplify block check when filtering invalid blocks
>   drm/edid: split out invalid block filtering to a separate function
>   drm/edid: track invalid blocks in drm_do_get_edid()
>   drm/edid: reduce magic when updating the EDID block checksum

With the few bugs I spotted fixed the series is
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> 
>  drivers/gpu/drm/drm_edid.c | 293 +++++++++++++++++++++----------------
>  include/drm/drm_edid.h     |   2 +-
>  2 files changed, 171 insertions(+), 124 deletions(-)
> 
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
  2022-03-30 13:05     ` [Intel-gfx] " Ville Syrjälä
@ 2022-03-31 18:46       ` Jani Nikula
  -1 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 18:46 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> +	if (valid_extensions != edid->extensions) {
>> +		struct edid *base;
>
> This one points to extension blocks too so using 
> struct edid doesn't seem entirely appropriate.

Settled on calling it struct edid *dest_block in v2 with hopes that's a
good enough compromise.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [Intel-gfx] [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid()
@ 2022-03-31 18:46       ` Jani Nikula
  0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2022-03-31 18:46 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, dri-devel

On Wed, 30 Mar 2022, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Mar 29, 2022 at 09:42:08PM +0300, Jani Nikula wrote:
>> +	if (valid_extensions != edid->extensions) {
>> +		struct edid *base;
>
> This one points to extension blocks too so using 
> struct edid doesn't seem entirely appropriate.

Settled on calling it struct edid *dest_block in v2 with hopes that's a
good enough compromise.

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2022-03-31 18:46 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-29 18:42 [PATCH 00/12] drm/edid: cleanup and refactoring around validity checks Jani Nikula
2022-03-29 18:42 ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 01/12] drm/edid: use struct edid * in drm_do_get_edid() Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-30 13:05   ` Ville Syrjälä
2022-03-30 13:05     ` [Intel-gfx] " Ville Syrjälä
2022-03-30 15:16     ` Jani Nikula
2022-03-30 15:16       ` [Intel-gfx] " Jani Nikula
2022-03-30 15:39       ` Ville Syrjälä
2022-03-30 15:39         ` [Intel-gfx] " Ville Syrjälä
2022-03-30 16:28         ` Jani Nikula
2022-03-30 16:28           ` [Intel-gfx] " Jani Nikula
2022-03-30 16:50           ` Ville Syrjälä
2022-03-30 16:50             ` [Intel-gfx] " Ville Syrjälä
2022-03-30 17:09             ` Jani Nikula
2022-03-30 21:01       ` Jani Nikula
2022-03-30 21:01         ` [Intel-gfx] " Jani Nikula
2022-03-31 18:46     ` Jani Nikula
2022-03-31 18:46       ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 02/12] drm/edid: clean up EDID block checksum functions Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 03/12] drm/edid: add edid_block_tag() helper to get the EDID extension tag Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 04/12] drm/edid: make drm_edid_header_is_valid() accept void pointer Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 05/12] drm/edid: clean up edid_is_zero() Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 06/12] drm/edid: split out edid_header_fix() Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 07/12] drm/edid: split drm_edid_block_valid() to check and act parts Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-31 14:54   ` Ville Syrjälä
2022-03-31 14:54     ` [Intel-gfx] " Ville Syrjälä
2022-03-31 15:54     ` Jani Nikula
2022-03-31 15:54       ` [Intel-gfx] " Jani Nikula
2022-03-31 16:49     ` Jani Nikula
2022-03-31 16:49       ` [Intel-gfx] " Jani Nikula
2022-03-31 16:58       ` Ville Syrjälä
2022-03-31 16:58         ` [Intel-gfx] " Ville Syrjälä
2022-03-29 18:42 ` [PATCH 08/12] drm/edid: use a better variable name for EDID block read retries Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-31 14:55   ` Ville Syrjälä
2022-03-31 14:55     ` [Intel-gfx] " Ville Syrjälä
2022-03-29 18:42 ` [PATCH 09/12] drm/edid: simplify block check when filtering invalid blocks Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 10/12] drm/edid: split out invalid block filtering to a separate function Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 11/12] drm/edid: track invalid blocks in drm_do_get_edid() Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-29 18:42 ` [PATCH 12/12] drm/edid: reduce magic when updating the EDID block checksum Jani Nikula
2022-03-29 18:42   ` [Intel-gfx] " Jani Nikula
2022-03-31 14:59   ` Ville Syrjälä
2022-03-31 14:59     ` [Intel-gfx] " Ville Syrjälä
2022-03-29 19:33 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/edid: cleanup and refactoring around validity checks Patchwork
2022-03-29 19:37 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2022-03-29 20:09 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-03-29 21:26 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2022-03-31 17:07 ` [PATCH 00/12] " Ville Syrjälä
2022-03-31 17:07   ` [Intel-gfx] " Ville Syrjälä

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.