[PATCH] drm/i915/gvt: Prevent divided by zero when calculating refresh rate

Zhenyu Wang zhenyuw at linux.intel.com
Wed Apr 21 09:46:38 UTC 2021


On 2021.04.16 16:33:55 +0800, Colin Xu wrote:
> To get refresh rate as vblank timer period and keep the precision, the
> calculation of rate is multiplied by 1000. However old logic was using:
> rate = pixel clock / (h * v / 1000). When the h/v total is invalid, like
> all 0, h * v / 1000 will be rounded to 0, which leads to a divided by 0
> fault.
> 
> 0 H/V are already checked above. Instead of divide after divide, refine
> the calculation to divide after multiply: "pixel clock * 1000 / (h * v)"
> Guest driver should guarantee the correctness of the timing regs' value.
> 
> Fixes: 6a4500c7b83f ("drm/i915/gvt: Get accurate vGPU virtual display
> refresh rate from vreg")
> 
> Reported-by: Zhenyu Wang <zhenyuw at linux.intel.com>
> Signed-off-by: Colin Xu <colin.xu at intel.com>
> ---

Reviewed-by: Zhenyu Wang <zhenyuw at linux.intel.com>

>  drivers/gpu/drm/i915/gvt/handlers.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
> index 477badfcb258..dda320749c65 100644
> --- a/drivers/gpu/drm/i915/gvt/handlers.c
> +++ b/drivers/gpu/drm/i915/gvt/handlers.c
> @@ -669,8 +669,8 @@ static void vgpu_update_refresh_rate(struct intel_vgpu *vgpu)
>  	link_n = vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A));
>  
>  	/* Get H/V total from transcoder timing */
> -	htotal = (vgpu_vreg_t(vgpu, HTOTAL(TRANSCODER_A)) >> TRANS_HTOTAL_SHIFT) + 1;
> -	vtotal = (vgpu_vreg_t(vgpu, VTOTAL(TRANSCODER_A)) >> TRANS_VTOTAL_SHIFT) + 1;
> +	htotal = (vgpu_vreg_t(vgpu, HTOTAL(TRANSCODER_A)) >> TRANS_HTOTAL_SHIFT);
> +	vtotal = (vgpu_vreg_t(vgpu, VTOTAL(TRANSCODER_A)) >> TRANS_VTOTAL_SHIFT);
>  
>  	if (dp_br && link_n && htotal && vtotal) {
>  		u64 pixel_clk = 0;
> @@ -682,7 +682,7 @@ static void vgpu_update_refresh_rate(struct intel_vgpu *vgpu)
>  		pixel_clk *= MSEC_PER_SEC;
>  
>  		/* Calcuate refresh rate by (pixel_clk / (h_total * v_total)) */
> -		new_rate = DIV64_U64_ROUND_CLOSEST(pixel_clk, div64_u64(mul_u32_u32(htotal, vtotal), MSEC_PER_SEC));
> +		new_rate = DIV64_U64_ROUND_CLOSEST(mul_u64_u32_shr(pixel_clk, MSEC_PER_SEC, 0), mul_u32_u32(htotal + 1, vtotal + 1));
>  
>  		if (*old_rate != new_rate)
>  			*old_rate = new_rate;
> -- 
> 2.31.1
> 
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gvt-dev/attachments/20210421/33b224b9/attachment.sig>


More information about the intel-gvt-dev mailing list