Re: [PATCH 2/2 V2] drm/radeon: properly handle vbios fake edid sizing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2024-07-23 16:51:21+0000, Alex Deucher wrote:
> The comment in the vbios structure says:
> // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
> 
> This fake edid struct has not been used in a long time, so I'm
> not sure if there were actually any boards out there with a non-128 byte
> EDID, but align the code with the comment.
> 
> Reported-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx>
> Link: https://lists.freedesktop.org/archives/amd-gfx/2024-June/109964.html
> Fixes: c324acd5032f ("drm/radeon/kms: parse the extended LCD info block")
> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>

Reviewed-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx>

> ---
> 
> V2: Incorporate comments.
>     Fix accidently dropped hunk.
> 
>  drivers/gpu/drm/radeon/radeon_atombios.c | 29 +++++++++++++-----------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
> index 97c4e10d0550..168f3f94003b 100644
> --- a/drivers/gpu/drm/radeon/radeon_atombios.c
> +++ b/drivers/gpu/drm/radeon/radeon_atombios.c
> @@ -1717,26 +1717,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
>  					fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
>  					if (fake_edid_record->ucFakeEDIDLength) {
>  						struct edid *edid;
> -						int edid_size =
> -							max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
> -						edid = kmalloc(edid_size, GFP_KERNEL);
> +						int edid_size;
> +
> +						if (fake_edid_record->ucFakeEDIDLength == 128)
> +							edid_size = fake_edid_record->ucFakeEDIDLength;
> +						else
> +							edid_size = fake_edid_record->ucFakeEDIDLength * 128;
> +						edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
> +							       edid_size, GFP_KERNEL);
>  						if (edid) {
> -							memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
> -							       fake_edid_record->ucFakeEDIDLength);
> -
>  							if (drm_edid_is_valid(edid)) {
>  								rdev->mode_info.bios_hardcoded_edid = edid;
>  								rdev->mode_info.bios_hardcoded_edid_size = edid_size;
> -							} else
> +							} else {
>  								kfree(edid);
> +							}
>  						}
> +						record += struct_size(fake_edid_record,
> +								      ucFakeEDIDString,
> +								      edid_size);
> +					} else {
> +						/* empty fake edid record must be 3 bytes long */
> +						record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
>  					}
> -					record += fake_edid_record->ucFakeEDIDLength ?
> -						  struct_size(fake_edid_record,
> -							      ucFakeEDIDString,
> -							      fake_edid_record->ucFakeEDIDLength) :
> -						  /* empty fake edid record must be 3 bytes long */
> -						  sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
>  					break;
>  				case LCD_PANEL_RESOLUTION_RECORD_TYPE:
>  					panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
> -- 
> 2.45.2
> 



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux