ARM i.MX: Fix a kernel panic in i2c_imx_clk_notifier_call().

Message ID m3va3sh5zl.fsf@t19.piap.pl
State New
Headers show
Series
  • ARM i.MX: Fix a kernel panic in i2c_imx_clk_notifier_call().
Related show

Commit Message

Krzysztof =?utf-8?Q?Ha=C5=82asa?= Dec. 17, 2018, 9:12 a.m.
90ad2cbe88c22d0215225ab9594eeead0eb24fde changed the i.MX I2C bus driver
to use a notifier whenever the base clock ("ipg" - 66 MHz peripheral
clock) rate changes.

Unfortunately one can't use the container_of() macro this way - the
first argument has to point to a member of the bigger struct (last
argument). Merely pointing to the same value isn't enough (the clk
variable which has its address passed to the macro is the clk in
notifier_block, not the one in imx_i2c_struct, even though both pointers
point to the same clk struct).

This bug causes kernel panic when the IPG clock rate changes (e.g. if
any clock derived from IPG changes).

Signed-off-by: Krzysztof Halasa <khalasa@piap.pl>

Comments

Uwe Kleine-König Dec. 17, 2018, 9:26 a.m. | #1
On Mon, Dec 17, 2018 at 10:12:14AM +0100, Krzysztof Hałasa wrote:
> 90ad2cbe88c22d0215225ab9594eeead0eb24fde changed the i.MX I2C bus driver
> to use a notifier whenever the base clock ("ipg" - 66 MHz peripheral
> clock) rate changes.
> 
> Unfortunately one can't use the container_of() macro this way - the
> first argument has to point to a member of the bigger struct (last
> argument). Merely pointing to the same value isn't enough (the clk
> variable which has its address passed to the macro is the clk in
> notifier_block, not the one in imx_i2c_struct, even though both pointers
> point to the same clk struct).
> 
> This bug causes kernel panic when the IPG clock rate changes (e.g. if
> any clock derived from IPG changes).
> 
> Signed-off-by: Krzysztof Halasa <khalasa@piap.pl>

I didn't look at the patch, but I suggest a Fixes: line here à la:

Fixes: 90ad2cbe88c2 ("i2c: imx: use clk notifier for rate changes")

Best regards
Uwe
Peter Rosin Dec. 17, 2018, 11:02 p.m. | #2
On 2018-12-17 10:12, Krzysztof Hałasa wrote:
> 90ad2cbe88c22d0215225ab9594eeead0eb24fde changed the i.MX I2C bus driver

This reference should ideally be in a fixes-tag, below...

> to use a notifier whenever the base clock ("ipg" - 66 MHz peripheral
> clock) rate changes.
> 
> Unfortunately one can't use the container_of() macro this way - the
> first argument has to point to a member of the bigger struct (last
> argument). Merely pointing to the same value isn't enough (the clk
> variable which has its address passed to the macro is the clk in
> notifier_block, not the one in imx_i2c_struct, even though both pointers
> point to the same clk struct).
> 
> This bug causes kernel panic when the IPG clock rate changes (e.g. if
> any clock derived from IPG changes).
> 

...right here.

Fixes: 90ad2cbe88c2 ("i2c: imx: use clk notifier for rate changes")
> Signed-off-by: Krzysztof Halasa <khalasa@piap.pl>
> 
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -510,9 +510,9 @@ static int i2c_imx_clk_notifier_call(struct notifier_block *nb,
>  				     unsigned long action, void *data)
>  {
>  	struct clk_notifier_data *ndata = data;
> -	struct imx_i2c_struct *i2c_imx = container_of(&ndata->clk,
> +	struct imx_i2c_struct *i2c_imx = container_of(nb,
>  						      struct imx_i2c_struct,
> -						      clk);
> +						      clk_change_nb);
>  
>  	if (action & POST_RATE_CHANGE)
>  		i2c_imx_set_clk(i2c_imx, ndata->new_rate);
>

Patch

--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -510,9 +510,9 @@  static int i2c_imx_clk_notifier_call(struct notifier_block *nb,
 				     unsigned long action, void *data)
 {
 	struct clk_notifier_data *ndata = data;
-	struct imx_i2c_struct *i2c_imx = container_of(&ndata->clk,
+	struct imx_i2c_struct *i2c_imx = container_of(nb,
 						      struct imx_i2c_struct,
-						      clk);
+						      clk_change_nb);
 
 	if (action & POST_RATE_CHANGE)
 		i2c_imx_set_clk(i2c_imx, ndata->new_rate);