Current:
uint32_t mclk_expected_pt_inc = ((uint64_t)pfd->mclk_expected_pt_inc
* ((uint64_t)pfd->ref_clk_expected_inc + (uint64_t)ref_clk_diff)
* pfd->ref_clk_scaling_numerator) >> SW_PLL_PFD_PRE_DIV_BITS;
Proposed fix:
uint32_t mclk_expected_pt_inc = ((uint64_t)pfd->mclk_expected_pt_inc
* (uint64_t)((int64_t)pfd->ref_clk_expected_inc + (int64_t)ref_clk_diff)
* pfd->ref_clk_scaling_numerator) >> SW_PLL_PFD_BITS;
The scaling term (uint64_t)pfd->ref_clk_expected_inc + (uint64_t)ref_clk_diff performs unsigned addition. If ref_clk_diff is negative (which is possible when ref_clk_pt is earlier than ref_clk_expected_pt), casting it to uint64_t will underflow to a huge value and make mclk_expected_pt_inc explode. Consider doing this add in a signed wide type (e.g. int64_t) and validating/clamping the result before converting to uint64_t for the multiply/shift.
Current:
uint32_t mclk_expected_pt_inc = ((uint64_t)pfd->mclk_expected_pt_inc
* ((uint64_t)pfd->ref_clk_expected_inc + (uint64_t)ref_clk_diff)
* pfd->ref_clk_scaling_numerator) >> SW_PLL_PFD_PRE_DIV_BITS;
Proposed fix:
uint32_t mclk_expected_pt_inc = ((uint64_t)pfd->mclk_expected_pt_inc
* (uint64_t)((int64_t)pfd->ref_clk_expected_inc + (int64_t)ref_clk_diff)
* pfd->ref_clk_scaling_numerator) >> SW_PLL_PFD_BITS;
The scaling term (uint64_t)pfd->ref_clk_expected_inc + (uint64_t)ref_clk_diff performs unsigned addition. If ref_clk_diff is negative (which is possible when ref_clk_pt is earlier than ref_clk_expected_pt), casting it to uint64_t will underflow to a huge value and make mclk_expected_pt_inc explode. Consider doing this add in a signed wide type (e.g. int64_t) and validating/clamping the result before converting to uint64_t for the multiply/shift.