diff mbox series

[CI,v2,12/12] drm/edid: add EDID block count and size helpers

Message ID 44265d5a3f64e9d7ad9984fee766f68d0b8bd473.1649670305.git.jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/edid: low level EDID block read refactoring etc. | expand

Commit Message

Jani Nikula April 11, 2022, 9:47 a.m. UTC
Add some helpers to figure out the EDID extension block count, block
count, size, pointers to blocks.

Unfortunately, we'll need to cast away the const in a few places where
we actually need to access the data.

v2: fix s/j/i/ introduced in a rebase

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 | 80 +++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 23 deletions(-)

Comments

kernel test robot April 11, 2022, 12:14 p.m. UTC | #1
Hi Jani,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[also build test WARNING on next-20220411]
[cannot apply to drm/drm-next drm-intel/for-linux-next v5.18-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220411/202204112055.cUmakJdJ-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
        git checkout ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/drm_edid.c: In function 'drm_do_get_edid':
>> drivers/gpu/drm/drm_edid.c:1664:21: warning: array subscript [128, 32640] is outside array bounds of 'struct edid[1]' [-Warray-bounds]
    1664 |         return block[0];
         |                ~~~~~^~~
   drivers/gpu/drm/drm_edid.c:2173:15: note: referencing an object of size 128 allocated by 'krealloc'
    2173 |         new = krealloc(edid, edid_size(edid), GFP_KERNEL);
         |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +1664 drivers/gpu/drm/drm_edid.c

c465bbc87ce372 Stefan Brüns 2014-11-30  1659  
4ba0f53ce685b0 Jani Nikula  2022-03-31  1660  static int edid_block_tag(const void *_block)
4ba0f53ce685b0 Jani Nikula  2022-03-31  1661  {
4ba0f53ce685b0 Jani Nikula  2022-03-31  1662  	const u8 *block = _block;
4ba0f53ce685b0 Jani Nikula  2022-03-31  1663  
4ba0f53ce685b0 Jani Nikula  2022-03-31 @1664  	return block[0];
4ba0f53ce685b0 Jani Nikula  2022-03-31  1665  }
4ba0f53ce685b0 Jani Nikula  2022-03-31  1666
kernel test robot April 11, 2022, 12:24 p.m. UTC | #2
Hi Jani,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[also build test WARNING on next-20220411]
[cannot apply to drm/drm-next drm-intel/for-linux-next v5.18-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: i386-randconfig-a001-20220411 (https://download.01.org/0day-ci/archive/20220411/202204112019.U9iIZWqP-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project c6e83f560f06cdfe8aa47b248d8bdc58f947274b)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
        git checkout ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_edid.c:2170:6: warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses]
           if (!edid_extension_block_count(edid) == 0)
               ^                                 ~~
   drivers/gpu/drm/drm_edid.c:2170:6: note: add parentheses after the '!' to evaluate the comparison first
           if (!edid_extension_block_count(edid) == 0)
               ^
                (                                    )
   drivers/gpu/drm/drm_edid.c:2170:6: note: add parentheses around left hand side expression to silence this warning
           if (!edid_extension_block_count(edid) == 0)
               ^
               (                                )
   1 warning generated.


vim +2170 drivers/gpu/drm/drm_edid.c

  2112	
  2113	/**
  2114	 * drm_do_get_edid - get EDID data using a custom EDID block read function
  2115	 * @connector: connector we're probing
  2116	 * @get_edid_block: EDID block read function
  2117	 * @data: private data passed to the block read function
  2118	 *
  2119	 * When the I2C adapter connected to the DDC bus is hidden behind a device that
  2120	 * exposes a different interface to read EDID blocks this function can be used
  2121	 * to get EDID data using a custom block read function.
  2122	 *
  2123	 * As in the general case the DDC bus is accessible by the kernel at the I2C
  2124	 * level, drivers must make all reasonable efforts to expose it as an I2C
  2125	 * adapter and use drm_get_edid() instead of abusing this function.
  2126	 *
  2127	 * The EDID may be overridden using debugfs override_edid or firmware EDID
  2128	 * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
  2129	 * order. Having either of them bypasses actual EDID reads.
  2130	 *
  2131	 * Return: Pointer to valid EDID or NULL if we couldn't find any.
  2132	 */
  2133	struct edid *drm_do_get_edid(struct drm_connector *connector,
  2134				     read_block_fn read_block,
  2135				     void *context)
  2136	{
  2137		enum edid_block_status status;
  2138		int i, invalid_blocks = 0;
  2139		struct edid *edid, *new;
  2140	
  2141		edid = drm_get_override_edid(connector);
  2142		if (edid)
  2143			goto ok;
  2144	
  2145		edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
  2146		if (!edid)
  2147			return NULL;
  2148	
  2149		status = edid_block_read(edid, 0, read_block, context);
  2150	
  2151		edid_block_status_print(status, edid, 0);
  2152	
  2153		if (status == EDID_BLOCK_READ_FAIL)
  2154			goto fail;
  2155	
  2156		/* FIXME: Clarify what a corrupt EDID actually means. */
  2157		if (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION)
  2158			connector->edid_corrupt = false;
  2159		else
  2160			connector->edid_corrupt = true;
  2161	
  2162		if (!edid_block_status_valid(status, edid_block_tag(edid))) {
  2163			if (status == EDID_BLOCK_ZERO)
  2164				connector->null_edid_counter++;
  2165	
  2166			connector_bad_edid(connector, edid, 1);
  2167			goto fail;
  2168		}
  2169	
> 2170		if (!edid_extension_block_count(edid) == 0)
  2171			goto ok;
  2172	
  2173		new = krealloc(edid, edid_size(edid), GFP_KERNEL);
  2174		if (!new)
  2175			goto fail;
  2176		edid = new;
  2177	
  2178		for (i = 1; i < edid_block_count(edid); i++) {
  2179			void *block = (void *)edid_block_data(edid, i);
  2180	
  2181			status = edid_block_read(block, i, read_block, context);
  2182	
  2183			edid_block_status_print(status, block, i);
  2184	
  2185			if (!edid_block_status_valid(status, edid_block_tag(block))) {
  2186				if (status == EDID_BLOCK_READ_FAIL)
  2187					goto fail;
  2188				invalid_blocks++;
  2189			}
  2190		}
  2191	
  2192		if (invalid_blocks) {
  2193			connector_bad_edid(connector, edid, edid_block_count(edid));
  2194	
  2195			edid = edid_filter_invalid_blocks(edid, invalid_blocks);
  2196		}
  2197	
  2198	ok:
  2199		return edid;
  2200	
  2201	fail:
  2202		kfree(edid);
  2203		return NULL;
  2204	}
  2205	EXPORT_SYMBOL_GPL(drm_do_get_edid);
  2206
Jani Nikula April 11, 2022, 1:54 p.m. UTC | #3
On Mon, 11 Apr 2022, kernel test robot <lkp@intel.com> wrote:
> Hi Jani,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on drm-tip/drm-tip]
> [also build test WARNING on next-20220411]
> [cannot apply to drm/drm-next drm-intel/for-linux-next v5.18-rc2]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
> base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
> config: i386-randconfig-a001-20220411 (https://download.01.org/0day-ci/archive/20220411/202204112019.U9iIZWqP-lkp@intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project c6e83f560f06cdfe8aa47b248d8bdc58f947274b)
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
>         git checkout ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All warnings (new ones prefixed by >>):
>
>>> drivers/gpu/drm/drm_edid.c:2170:6: warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses]
>            if (!edid_extension_block_count(edid) == 0)
>                ^                                 ~~
>    drivers/gpu/drm/drm_edid.c:2170:6: note: add parentheses after the '!' to evaluate the comparison first
>            if (!edid_extension_block_count(edid) == 0)
>                ^
>                 (                                    )
>    drivers/gpu/drm/drm_edid.c:2170:6: note: add parentheses around left hand side expression to silence this warning
>            if (!edid_extension_block_count(edid) == 0)
>                ^
>                (                                )
>    1 warning generated.

Whoops, thanks for the report!

BR,
Jani.

>
>
> vim +2170 drivers/gpu/drm/drm_edid.c
>
>   2112	
>   2113	/**
>   2114	 * drm_do_get_edid - get EDID data using a custom EDID block read function
>   2115	 * @connector: connector we're probing
>   2116	 * @get_edid_block: EDID block read function
>   2117	 * @data: private data passed to the block read function
>   2118	 *
>   2119	 * When the I2C adapter connected to the DDC bus is hidden behind a device that
>   2120	 * exposes a different interface to read EDID blocks this function can be used
>   2121	 * to get EDID data using a custom block read function.
>   2122	 *
>   2123	 * As in the general case the DDC bus is accessible by the kernel at the I2C
>   2124	 * level, drivers must make all reasonable efforts to expose it as an I2C
>   2125	 * adapter and use drm_get_edid() instead of abusing this function.
>   2126	 *
>   2127	 * The EDID may be overridden using debugfs override_edid or firmware EDID
>   2128	 * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
>   2129	 * order. Having either of them bypasses actual EDID reads.
>   2130	 *
>   2131	 * Return: Pointer to valid EDID or NULL if we couldn't find any.
>   2132	 */
>   2133	struct edid *drm_do_get_edid(struct drm_connector *connector,
>   2134				     read_block_fn read_block,
>   2135				     void *context)
>   2136	{
>   2137		enum edid_block_status status;
>   2138		int i, invalid_blocks = 0;
>   2139		struct edid *edid, *new;
>   2140	
>   2141		edid = drm_get_override_edid(connector);
>   2142		if (edid)
>   2143			goto ok;
>   2144	
>   2145		edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
>   2146		if (!edid)
>   2147			return NULL;
>   2148	
>   2149		status = edid_block_read(edid, 0, read_block, context);
>   2150	
>   2151		edid_block_status_print(status, edid, 0);
>   2152	
>   2153		if (status == EDID_BLOCK_READ_FAIL)
>   2154			goto fail;
>   2155	
>   2156		/* FIXME: Clarify what a corrupt EDID actually means. */
>   2157		if (status == EDID_BLOCK_OK || status == EDID_BLOCK_VERSION)
>   2158			connector->edid_corrupt = false;
>   2159		else
>   2160			connector->edid_corrupt = true;
>   2161	
>   2162		if (!edid_block_status_valid(status, edid_block_tag(edid))) {
>   2163			if (status == EDID_BLOCK_ZERO)
>   2164				connector->null_edid_counter++;
>   2165	
>   2166			connector_bad_edid(connector, edid, 1);
>   2167			goto fail;
>   2168		}
>   2169	
>> 2170		if (!edid_extension_block_count(edid) == 0)
>   2171			goto ok;
>   2172	
>   2173		new = krealloc(edid, edid_size(edid), GFP_KERNEL);
>   2174		if (!new)
>   2175			goto fail;
>   2176		edid = new;
>   2177	
>   2178		for (i = 1; i < edid_block_count(edid); i++) {
>   2179			void *block = (void *)edid_block_data(edid, i);
>   2180	
>   2181			status = edid_block_read(block, i, read_block, context);
>   2182	
>   2183			edid_block_status_print(status, block, i);
>   2184	
>   2185			if (!edid_block_status_valid(status, edid_block_tag(block))) {
>   2186				if (status == EDID_BLOCK_READ_FAIL)
>   2187					goto fail;
>   2188				invalid_blocks++;
>   2189			}
>   2190		}
>   2191	
>   2192		if (invalid_blocks) {
>   2193			connector_bad_edid(connector, edid, edid_block_count(edid));
>   2194	
>   2195			edid = edid_filter_invalid_blocks(edid, invalid_blocks);
>   2196		}
>   2197	
>   2198	ok:
>   2199		return edid;
>   2200	
>   2201	fail:
>   2202		kfree(edid);
>   2203		return NULL;
>   2204	}
>   2205	EXPORT_SYMBOL_GPL(drm_do_get_edid);
>   2206
Jani Nikula April 11, 2022, 1:57 p.m. UTC | #4
On Mon, 11 Apr 2022, kernel test robot <lkp@intel.com> wrote:
> Hi Jani,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on drm-tip/drm-tip]
> [also build test WARNING on next-20220411]
> [cannot apply to drm/drm-next drm-intel/for-linux-next v5.18-rc2]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
> base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
> config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220411/202204112055.cUmakJdJ-lkp@intel.com/config)
> compiler: arceb-elf-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Jani-Nikula/drm-edid-low-level-EDID-block-read-refactoring-etc/20220411-175027
>         git checkout ba74d3cc8cc1b6ba4c34a039e797994ddbc77567
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash drivers/gpu/drm/
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All warnings (new ones prefixed by >>):
>
>    drivers/gpu/drm/drm_edid.c: In function 'drm_do_get_edid':
>>> drivers/gpu/drm/drm_edid.c:1664:21: warning: array subscript [128, 32640] is outside array bounds of 'struct edid[1]' [-Warray-bounds]
>     1664 |         return block[0];
>          |                ~~~~~^~~
>    drivers/gpu/drm/drm_edid.c:2173:15: note: referencing an object of size 128 allocated by 'krealloc'
>     2173 |         new = krealloc(edid, edid_size(edid), GFP_KERNEL);
>          |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I presume this is caused by the other blunder.

BR,
Jani.

>
>
> vim +1664 drivers/gpu/drm/drm_edid.c
>
> c465bbc87ce372 Stefan Brüns 2014-11-30  1659  
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1660  static int edid_block_tag(const void *_block)
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1661  {
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1662  	const u8 *block = _block;
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1663  
> 4ba0f53ce685b0 Jani Nikula  2022-03-31 @1664  	return block[0];
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1665  }
> 4ba0f53ce685b0 Jani Nikula  2022-03-31  1666
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0933a5c44998..c8148e5b9969 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1568,6 +1568,38 @@  static const struct drm_display_mode edid_4k_modes[] = {
 
 /*** DDC fetch and block validation ***/
 
+static int edid_extension_block_count(const struct edid *edid)
+{
+	return edid->extensions;
+}
+
+static int edid_block_count(const struct edid *edid)
+{
+	return edid_extension_block_count(edid) + 1;
+}
+
+static int edid_size_by_blocks(int num_blocks)
+{
+	return num_blocks * EDID_LENGTH;
+}
+
+static int edid_size(const struct edid *edid)
+{
+	return edid_size_by_blocks(edid_block_count(edid));
+}
+
+static const void *edid_block_data(const struct edid *edid, int index)
+{
+	BUILD_BUG_ON(sizeof(*edid) != EDID_LENGTH);
+
+	return edid + index;
+}
+
+static const void *edid_extension_block_data(const struct edid *edid, int index)
+{
+	return edid_block_data(edid, index + 1);
+}
+
 static const u8 edid_header[] = {
 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
 };
@@ -1654,8 +1686,8 @@  bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2)
 		return false;
 
 	if (edid1) {
-		edid1_len = EDID_LENGTH * (1 + edid1->extensions);
-		edid2_len = EDID_LENGTH * (1 + edid2->extensions);
+		edid1_len = edid_size(edid1);
+		edid2_len = edid_size(edid2);
 
 		if (edid1_len != edid2_len)
 			return false;
@@ -1865,14 +1897,16 @@  EXPORT_SYMBOL(drm_edid_block_valid);
 bool drm_edid_is_valid(struct edid *edid)
 {
 	int i;
-	u8 *raw = (u8 *)edid;
 
 	if (!edid)
 		return false;
 
-	for (i = 0; i <= edid->extensions; i++)
-		if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
+	for (i = 0; i < edid_block_count(edid); i++) {
+		void *block = (void *)edid_block_data(edid, i);
+
+		if (!drm_edid_block_valid(block, i, true, NULL))
 			return false;
+	}
 
 	return true;
 }
@@ -1885,13 +1919,13 @@  static struct edid *edid_filter_invalid_blocks(const struct edid *edid,
 	int valid_extensions = edid->extensions - invalid_blocks;
 	int i;
 
-	new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL);
+	new = kmalloc(edid_size_by_blocks(valid_extensions + 1), GFP_KERNEL);
 	if (!new)
 		goto out;
 
 	dest_block = new;
-	for (i = 0; i <= edid->extensions; i++) {
-		const void *block = edid + i;
+	for (i = 0; i < edid_block_count(edid); i++) {
+		const void *block = edid_block_data(edid, i);
 
 		if (edid_block_valid(block, i == 0))
 			memcpy(dest_block++, block, EDID_LENGTH);
@@ -2101,7 +2135,7 @@  struct edid *drm_do_get_edid(struct drm_connector *connector,
 			     void *context)
 {
 	enum edid_block_status status;
-	int j, invalid_blocks = 0;
+	int i, invalid_blocks = 0;
 	struct edid *edid, *new;
 
 	edid = drm_get_override_edid(connector);
@@ -2133,20 +2167,20 @@  struct edid *drm_do_get_edid(struct drm_connector *connector,
 		goto fail;
 	}
 
-	if (edid->extensions == 0)
+	if (!edid_extension_block_count(edid) == 0)
 		goto ok;
 
-	new = krealloc(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+	new = krealloc(edid, edid_size(edid), GFP_KERNEL);
 	if (!new)
 		goto fail;
 	edid = new;
 
-	for (j = 1; j <= edid->extensions; j++) {
-		void *block = edid + j;
+	for (i = 1; i < edid_block_count(edid); i++) {
+		void *block = (void *)edid_block_data(edid, i);
 
-		status = edid_block_read(block, j, read_block, context);
+		status = edid_block_read(block, i, read_block, context);
 
-		edid_block_status_print(status, block, j);
+		edid_block_status_print(status, block, i);
 
 		if (!edid_block_status_valid(status, edid_block_tag(block))) {
 			if (status == EDID_BLOCK_READ_FAIL)
@@ -2156,7 +2190,7 @@  struct edid *drm_do_get_edid(struct drm_connector *connector,
 	}
 
 	if (invalid_blocks) {
-		connector_bad_edid(connector, edid, edid->extensions + 1);
+		connector_bad_edid(connector, edid, edid_block_count(edid));
 
 		edid = edid_filter_invalid_blocks(edid, invalid_blocks);
 	}
@@ -2321,7 +2355,7 @@  EXPORT_SYMBOL(drm_get_edid_switcheroo);
  */
 struct edid *drm_edid_duplicate(const struct edid *edid)
 {
-	return kmemdup(edid, (edid->extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+	return kmemdup(edid, edid_size(edid), GFP_KERNEL);
 }
 EXPORT_SYMBOL(drm_edid_duplicate);
 
@@ -2505,8 +2539,8 @@  drm_for_each_detailed_block(const struct edid *edid, detailed_cb *cb, void *clos
 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
 		cb(&(edid->detailed_timings[i]), closure);
 
-	for (i = 1; i <= edid->extensions; i++) {
-		const u8 *ext = (const u8 *)edid + (i * EDID_LENGTH);
+	for (i = 0; i < edid_extension_block_count(edid); i++) {
+		const u8 *ext = edid_extension_block_data(edid, i);
 
 		switch (*ext) {
 		case CEA_EXT:
@@ -3476,17 +3510,17 @@  const u8 *drm_find_edid_extension(const struct edid *edid,
 	int i;
 
 	/* No EDID or EDID extensions */
-	if (edid == NULL || edid->extensions == 0)
+	if (!edid || !edid_extension_block_count(edid))
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid->extensions; i++) {
-		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
+	for (i = *ext_index; i < edid_extension_block_count(edid); i++) {
+		edid_ext = edid_extension_block_data(edid, i);
 		if (edid_block_tag(edid_ext) == ext_id)
 			break;
 	}
 
-	if (i >= edid->extensions)
+	if (i >= edid_extension_block_count(edid))
 		return NULL;
 
 	*ext_index = i + 1;