Message ID | 20230706100454.28998-1-shuijing.li@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | pwm: mtk_disp: fix disp_pwm coverity issue | expand |
On 06/07/2023 12:04, Shuijing Li wrote: > There is a coverity issue in the original mtk_disp_pwm_get_state() > function. In function call DIV64_U64_ROUND_UP, division by expression > Which may be zero has undefined behavior. > Fix this accordingly. > > Signed-off-by: Shuijing Li <shuijing.li@mediatek.com> > --- > drivers/pwm/pwm-mtk-disp.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c > index 79e321e96f56..ca00058a6ef4 100644 > --- a/drivers/pwm/pwm-mtk-disp.c > +++ b/drivers/pwm/pwm-mtk-disp.c > @@ -196,6 +196,14 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, > return err; > } > > + rate = clk_get_rate(mdp->clk_main); > + if (rate <= 0) { > + dev_err(chip->dev, "Can't get rate: %pe\n", ERR_PTR(rate)); > + clk_disable_unprepare(mdp->clk_mm); > + clk_disable_unprepare(mdp->clk_main); > + return err; > + } > + > /* > * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable > * registers double buffer and manual commit to working register before > @@ -206,7 +214,6 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, > mdp->data->bls_debug_mask, > mdp->data->bls_debug_mask); > > - rate = clk_get_rate(mdp->clk_main); > con0 = readl(mdp->base + mdp->data->con0); > con1 = readl(mdp->base + mdp->data->con1); > pwm_en = readl(mdp->base + DISP_PWM_EN); IMHO, it should be done int the function `mtk_disp_pwm_apply` too. Do you agree ?
Il 06/07/23 14:29, Alexandre Mergnat ha scritto: > > > On 06/07/2023 12:04, Shuijing Li wrote: >> There is a coverity issue in the original mtk_disp_pwm_get_state() >> function. In function call DIV64_U64_ROUND_UP, division by expression >> Which may be zero has undefined behavior. >> Fix this accordingly. >> >> Signed-off-by: Shuijing Li <shuijing.li@mediatek.com> >> --- >> drivers/pwm/pwm-mtk-disp.c | 9 ++++++++- >> 1 file changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c >> index 79e321e96f56..ca00058a6ef4 100644 >> --- a/drivers/pwm/pwm-mtk-disp.c >> +++ b/drivers/pwm/pwm-mtk-disp.c >> @@ -196,6 +196,14 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, >> return err; >> } >> + rate = clk_get_rate(mdp->clk_main); >> + if (rate <= 0) { >> + dev_err(chip->dev, "Can't get rate: %pe\n", ERR_PTR(rate)); >> + clk_disable_unprepare(mdp->clk_mm); >> + clk_disable_unprepare(mdp->clk_main); >> + return err; >> + } >> + >> /* >> * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable >> * registers double buffer and manual commit to working register before >> @@ -206,7 +214,6 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, >> mdp->data->bls_debug_mask, >> mdp->data->bls_debug_mask); >> - rate = clk_get_rate(mdp->clk_main); >> con0 = readl(mdp->base + mdp->data->con0); >> con1 = readl(mdp->base + mdp->data->con1); >> pwm_en = readl(mdp->base + DISP_PWM_EN); > > IMHO, it should be done int the function `mtk_disp_pwm_apply` too. > Do you agree ? > I think that realistically this will never happen. We're getting the clk_main clock's handle at probe time (or fail and get out), then the PWM clock never has the CLK_GET_RATE_NOCACHE flag, as there wouldn't be any reason to not cache the rates for this clock. But even if we had the CLK_GET_RATE_NOCACHE flag, it wouldn't change much, as our validation actually happens at probe time... This means that our call to clk_get_rate is guaranteed to have a not NULL pointer to this clock's `struct clk_core` and, unless the declaration of this clock in the clock controller driver was wrong, for it, or for its parent, the branch... if (!core->num_parents || core->parent) return core->rate; ...is always satisfied, so, in the end, this instance of clk_get_rate() can't really return zero. If you got such an issue, I suggest to check what the problem is, as it is likely to be outside of this driver. ...that, besides the fact that the proposed code is incorrect, as clk_get_rate() returns an `unsigned long`, so `rate` can never be less than zero, anyway. Cheers, Angelo
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 79e321e96f56..ca00058a6ef4 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -196,6 +196,14 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, return err; } + rate = clk_get_rate(mdp->clk_main); + if (rate <= 0) { + dev_err(chip->dev, "Can't get rate: %pe\n", ERR_PTR(rate)); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); + return err; + } + /* * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable * registers double buffer and manual commit to working register before @@ -206,7 +214,6 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, mdp->data->bls_debug_mask, mdp->data->bls_debug_mask); - rate = clk_get_rate(mdp->clk_main); con0 = readl(mdp->base + mdp->data->con0); con1 = readl(mdp->base + mdp->data->con1); pwm_en = readl(mdp->base + DISP_PWM_EN);
There is a coverity issue in the original mtk_disp_pwm_get_state() function. In function call DIV64_U64_ROUND_UP, division by expression Which may be zero has undefined behavior. Fix this accordingly. Signed-off-by: Shuijing Li <shuijing.li@mediatek.com> --- drivers/pwm/pwm-mtk-disp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)