Skip to contentSkip to conversation

clk: fractional-divider: cast parent_rate to u64 before multiplying

PATCH In review Heiko Stübner 1 participant 3 messages Aug 28, 2014 – Sep 10, 2014 1 message not in the archive Common clk

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 clk: fractional-divider: cast parent_rate to u64 before multiplying

On 32bit architectures, like ARM calculating the fractional rate will do the multiplication before converting the value to u64 when it gets assigned to ret, which can produce overflows.

The error in question happened with a parent_rate of 386MHz, m = 3000, n = 60000, which resulted in a wrong rate value of 15812Hz.

Therefore cast parent_rate to u64 to make sure the multiplication happens in a 64bit space and produces the correct 192MHz in the example.

---
 drivers/clk/clk-fractional-divider.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-fractional-divider.c +1 -1
index ede685c..82a59d0 100644
@@ -36,7 +36,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 	m = (val & fd->mmask) >> fd->mshift;
 	n = (val & fd->nmask) >> fd->nshift;
 
-	ret = parent_rate * m;
+	ret = (u64)parent_rate * m;
 	do_div(ret, n);
 
 	return ret;
Signature · 1 line
2.0.1

A message that is not in the archive (sent off-list or not yet received): 20140902002629.5251.42667@quantum

#2 lore raw

Am Montag, 1. September 2014, 17:26:29 schrieb Mike Turquette:

Quoted 12 lines

Quoting Heiko Stübner (2014-08-28 03:46:10)

Quoted 10 lines

On 32bit architectures, like ARM calculating the fractional rate will do the multiplication before converting the value to u64 when it gets assigned to ret, which can produce overflows.

The error in question happened with a parent_rate of 386MHz, m = 3000, n = 60000, which resulted in a wrong rate value of 15812Hz.

Therefore cast parent_rate to u64 to make sure the multiplication happens in a 64bit space and produces the correct 192MHz in the example.

Quoted 8 lines
Quoted 1 line

Looks good to me. Have you observed this issue using the vanilla kernel.org sources or on a downstream tree? I'm trying to decide if I should take this into clk-fixes or clk-next.

If this doesn't happen in practice on any merged platform then I'll take it for 3.18.

It happens on the Rockchip platform with the newly added fractional branches you just applied ... so it doesn't look like anybody else is affected right now.

Heiko

Quoted 24 lines

Regards,
Mike

Quoted 20 lines

---

 drivers/clk/clk-fractional-divider.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(quoted diff) +0 -0

b/drivers/clk/clk-fractional-divider.c index ede685c..82a59d0 100644

drivers/clk/clk-fractional-divider.c +1 -1
@@ -36,7 +36,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw
 *hw,> 
        m = (val & fd->mmask) >> fd->mshift;
        n = (val & fd->nmask) >> fd->nshift;
 
-       ret = parent_rate * m;
+       ret = (u64)parent_rate * m;
 
        do_div(ret, n);
        
        return ret;
#3 lore raw

Hi Mike,

Am Dienstag, 2. September 2014, 09:33:21 schrieb Heiko Stübner:

Quoted 19 lines

Am Montag, 1. September 2014, 17:26:29 schrieb Mike Turquette:

Quoted 18 lines

Quoting Heiko Stübner (2014-08-28 03:46:10)

Quoted 11 lines

On 32bit architectures, like ARM calculating the fractional rate will do the multiplication before converting the value to u64 when it gets assigned to ret, which can produce overflows.

The error in question happened with a parent_rate of 386MHz, m = 3000, n = 60000, which resulted in a wrong rate value of 15812Hz.

Therefore cast parent_rate to u64 to make sure the multiplication happens in a 64bit space and produces the correct 192MHz in the example.

Looks good to me. Have you observed this issue using the vanilla kernel.org sources or on a downstream tree? I'm trying to decide if I should take this into clk-fixes or clk-next.

Quoted 6 lines
Quoted 2 lines

If this doesn't happen in practice on any merged platform then I'll take it for 3.18.

It happens on the Rockchip platform with the newly added fractional branches you just applied ... so it doesn't look like anybody else is affected right now.

will you take this one into clk-next?

Thanks
Heiko

Quoted 28 lines

Heiko

Quoted 24 lines

Regards,
Mike

Quoted 21 lines

---

 drivers/clk/clk-fractional-divider.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(quoted diff) +0 -0

b/drivers/clk/clk-fractional-divider.c index ede685c..82a59d0 100644

drivers/clk/clk-fractional-divider.c +1 -1
@@ -36,7 +36,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw
 *hw,>
 
        m = (val & fd->mmask) >> fd->mshift;
        n = (val & fd->nmask) >> fd->nshift;
 
-       ret = parent_rate * m;
+       ret = (u64)parent_rate * m;
 
        do_div(ret, n);
        
        return ret;