[PATCH v2] drm/i915/edp: Check supported link rates DPCD read

Nikita Zhandarovich posted 1 patch 1 week, 2 days ago
drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
[PATCH v2] drm/i915/edp: Check supported link rates DPCD read
Posted by Nikita Zhandarovich 1 week, 2 days ago
intel_edp_set_sink_rates() reads DP_SUPPORTED_LINK_RATES into a local
stack array and then parses the array unconditionally. If the read
fails, the array contents are not valid and may result in bogus sink
link rates being used.

Use drm_dp_dpcd_read_data() and clear the sink rate array on failure,
so the existing parser falls back to the default sink rate handling.

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool SVACE.

Fixes: 68f357cb7347 ("drm/i915/dp: generate and cache sink rate array for all DP, not just eDP 1.4")
Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
---
v1 -> v2:
- Use drm_dp_dpcd_read_data() instead of drm_dp_dpcd_read().
- Avoid the goto by clearing sink_rates on read failure, as suggested by
  Jani Nikula.
- Adjust patch description.

 drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 6ef2a0043cda..5c3e816b0135 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4678,10 +4678,17 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
 
 	if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
 		__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
+		int ret;
 		int i;
 
-		drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
-				 sink_rates, sizeof(sink_rates));
+		ret = drm_dp_dpcd_read_data(&intel_dp->aux,
+					    DP_SUPPORTED_LINK_RATES,
+					    sink_rates, sizeof(sink_rates));
+		if (ret < 0) {
+			drm_dbg_kms(display->drm,
+				    "Unable to read eDP supported link rates, using default rates\n");
+			memset(sink_rates, 0, sizeof(sink_rates));
+		}
 
 		for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
 			int rate;
Re: [PATCH v2] drm/i915/edp: Check supported link rates DPCD read
Posted by Jani Nikula 1 week, 2 days ago
On Fri, 29 May 2026, Nikita Zhandarovich <n.zhandarovich@fintech.ru> wrote:
> intel_edp_set_sink_rates() reads DP_SUPPORTED_LINK_RATES into a local
> stack array and then parses the array unconditionally. If the read
> fails, the array contents are not valid and may result in bogus sink
> link rates being used.
>
> Use drm_dp_dpcd_read_data() and clear the sink rate array on failure,
> so the existing parser falls back to the default sink rate handling.
>
> Found by Linux Verification Center (linuxtesting.org) with static
> analysis tool SVACE.
>
> Fixes: 68f357cb7347 ("drm/i915/dp: generate and cache sink rate array for all DP, not just eDP 1.4")
> Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>

Reviewed-by: Jani Nikula <jani.nikula@intel.com>

> ---
> v1 -> v2:
> - Use drm_dp_dpcd_read_data() instead of drm_dp_dpcd_read().
> - Avoid the goto by clearing sink_rates on read failure, as suggested by
>   Jani Nikula.
> - Adjust patch description.
>
>  drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 6ef2a0043cda..5c3e816b0135 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4678,10 +4678,17 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
>  
>  	if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
>  		__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
> +		int ret;
>  		int i;
>  
> -		drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
> -				 sink_rates, sizeof(sink_rates));
> +		ret = drm_dp_dpcd_read_data(&intel_dp->aux,
> +					    DP_SUPPORTED_LINK_RATES,
> +					    sink_rates, sizeof(sink_rates));
> +		if (ret < 0) {
> +			drm_dbg_kms(display->drm,
> +				    "Unable to read eDP supported link rates, using default rates\n");
> +			memset(sink_rates, 0, sizeof(sink_rates));
> +		}
>  
>  		for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
>  			int rate;

-- 
Jani Nikula, Intel
Re: [PATCH v2] drm/i915/edp: Check supported link rates DPCD read
Posted by Jani Nikula 5 days ago
On Fri, 29 May 2026, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Fri, 29 May 2026, Nikita Zhandarovich <n.zhandarovich@fintech.ru> wrote:
>> intel_edp_set_sink_rates() reads DP_SUPPORTED_LINK_RATES into a local
>> stack array and then parses the array unconditionally. If the read
>> fails, the array contents are not valid and may result in bogus sink
>> link rates being used.
>>
>> Use drm_dp_dpcd_read_data() and clear the sink rate array on failure,
>> so the existing parser falls back to the default sink rate handling.
>>
>> Found by Linux Verification Center (linuxtesting.org) with static
>> analysis tool SVACE.
>>
>> Fixes: 68f357cb7347 ("drm/i915/dp: generate and cache sink rate array for all DP, not just eDP 1.4")
>> Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>

And pushed to drm-intel-next, thanks for the patch.

>
>> ---
>> v1 -> v2:
>> - Use drm_dp_dpcd_read_data() instead of drm_dp_dpcd_read().
>> - Avoid the goto by clearing sink_rates on read failure, as suggested by
>>   Jani Nikula.
>> - Adjust patch description.
>>
>>  drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 6ef2a0043cda..5c3e816b0135 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -4678,10 +4678,17 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
>>  
>>  	if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
>>  		__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
>> +		int ret;
>>  		int i;
>>  
>> -		drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
>> -				 sink_rates, sizeof(sink_rates));
>> +		ret = drm_dp_dpcd_read_data(&intel_dp->aux,
>> +					    DP_SUPPORTED_LINK_RATES,
>> +					    sink_rates, sizeof(sink_rates));
>> +		if (ret < 0) {
>> +			drm_dbg_kms(display->drm,
>> +				    "Unable to read eDP supported link rates, using default rates\n");
>> +			memset(sink_rates, 0, sizeof(sink_rates));
>> +		}
>>  
>>  		for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
>>  			int rate;

-- 
Jani Nikula, Intel