2022-12-14 16:42:10

by Hanna Hawa

[permalink] [raw]
Subject: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

From: Lareine Khawaly <[email protected]>

In functions i2c_dw_scl_lcnt() and i2c_dw_scl_hcnt() may have overflow
by depending on the values of the given parameters including the ic_clk.
For example in our use case where ic_clk is larger than one million,
multiplication of ic_clk * 4700 will result in 32 bit overflow.

Make the ic_clk to be u64 parameter to avoid the overflow.

Change Log v1->v2:
- Update commit message and add fix tag.

Fixes: 2373f6b9744d ("i2c-designware: split of i2c-designware.c into core and bus specific parts")
Signed-off-by: Lareine Khawaly <[email protected]>
Signed-off-by: Hanna Hawa <[email protected]>
---
drivers/i2c/busses/i2c-designware-common.c | 4 ++--
drivers/i2c/busses/i2c-designware-core.h | 4 ++--
drivers/i2c/busses/i2c-designware-master.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c
index c023b691441e..61a6b7bb8935 100644
--- a/drivers/i2c/busses/i2c-designware-common.c
+++ b/drivers/i2c/busses/i2c-designware-common.c
@@ -332,7 +332,7 @@ void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev)
}
EXPORT_SYMBOL_GPL(i2c_dw_adjust_bus_speed);

-u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
+u32 i2c_dw_scl_hcnt(u64 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
{
/*
* DesignWare I2C core doesn't seem to have solid strategy to meet
@@ -370,7 +370,7 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
return DIV_ROUND_CLOSEST(ic_clk * (tSYMBOL + tf), MICRO) - 3 + offset;
}

-u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
+u32 i2c_dw_scl_lcnt(u64 ic_clk, u32 tLOW, u32 tf, int offset)
{
/*
* Conditional expression:
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 4d3a3b464ecd..aaba6f9977b6 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -319,8 +319,8 @@ struct i2c_dw_semaphore_callbacks {
};

int i2c_dw_init_regmap(struct dw_i2c_dev *dev);
-u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
-u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
+u32 i2c_dw_scl_hcnt(u64 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
+u32 i2c_dw_scl_lcnt(u64 ic_clk, u32 tLOW, u32 tf, int offset);
int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev);
unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev);
int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare);
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 16a4cd68567c..bfa2b37fb3f7 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -44,7 +44,7 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
u32 sda_falling_time, scl_falling_time;
struct i2c_timings *t = &dev->timings;
const char *fp_str = "";
- u32 ic_clk;
+ u64 ic_clk;
int ret;

ret = i2c_dw_acquire_lock(dev);
--
2.38.1


2022-12-14 16:50:32

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

On Wed, Dec 14, 2022 at 06:18:07PM +0200, Andy Shevchenko wrote:
> On Wed, Dec 14, 2022 at 06:12:12PM +0200, Andy Shevchenko wrote:
> > On Wed, Dec 14, 2022 at 03:41:17PM +0000, Hanna Hawa wrote:
> > > From: Lareine Khawaly <[email protected]>
> > >
> > > In functions i2c_dw_scl_lcnt() and i2c_dw_scl_hcnt() may have overflow
> > > by depending on the values of the given parameters including the ic_clk.
> > > For example in our use case where ic_clk is larger than one million,
> > > multiplication of ic_clk * 4700 will result in 32 bit overflow.
> > >
> > > Make the ic_clk to be u64 parameter to avoid the overflow.
> >
> > Below my comment, after addressing it,
> > Reviewed-by: Andy Shevchenko <[email protected]>
>
> Sorry, was too quick. I have to withdraw my tag since this patch obviously
> breaks a compilation for Intel Quark chip.

ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_hcnt':
i2c-designware-common.c:(.text+0x5fe): undefined reference to `__udivdi3'
ld: i2c-designware-common.c:(.text+0x634): undefined reference to `__udivdi3'
ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_lcnt':
i2c-designware-common.c:(.text+0x679): undefined reference to `__udivdi3'

> Please, test it carefully and submit new version when it will be ready.

--
With Best Regards,
Andy Shevchenko


2022-12-14 17:27:30

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

On Wed, Dec 14, 2022 at 06:12:12PM +0200, Andy Shevchenko wrote:
> On Wed, Dec 14, 2022 at 03:41:17PM +0000, Hanna Hawa wrote:
> > From: Lareine Khawaly <[email protected]>
> >
> > In functions i2c_dw_scl_lcnt() and i2c_dw_scl_hcnt() may have overflow
> > by depending on the values of the given parameters including the ic_clk.
> > For example in our use case where ic_clk is larger than one million,
> > multiplication of ic_clk * 4700 will result in 32 bit overflow.
> >
> > Make the ic_clk to be u64 parameter to avoid the overflow.
>
> Below my comment, after addressing it,
> Reviewed-by: Andy Shevchenko <[email protected]>

Sorry, was too quick. I have to withdraw my tag since this patch obviously
breaks a compilation for Intel Quark chip.

Please, test it carefully and submit new version when it will be ready.

--
With Best Regards,
Andy Shevchenko


2022-12-14 17:43:12

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

On Wed, Dec 14, 2022 at 03:41:17PM +0000, Hanna Hawa wrote:
> From: Lareine Khawaly <[email protected]>
>
> In functions i2c_dw_scl_lcnt() and i2c_dw_scl_hcnt() may have overflow
> by depending on the values of the given parameters including the ic_clk.
> For example in our use case where ic_clk is larger than one million,
> multiplication of ic_clk * 4700 will result in 32 bit overflow.
>
> Make the ic_clk to be u64 parameter to avoid the overflow.

Below my comment, after addressing it,
Reviewed-by: Andy Shevchenko <[email protected]>

> Change Log v1->v2:
> - Update commit message and add fix tag.

Wrong location of the changelog...

> Fixes: 2373f6b9744d ("i2c-designware: split of i2c-designware.c into core and bus specific parts")
> Signed-off-by: Lareine Khawaly <[email protected]>
> Signed-off-by: Hanna Hawa <[email protected]>
> ---

...should be somewhere here.

> drivers/i2c/busses/i2c-designware-common.c | 4 ++--
> drivers/i2c/busses/i2c-designware-core.h | 4 ++--
> drivers/i2c/busses/i2c-designware-master.c | 2 +-
> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c
> index c023b691441e..61a6b7bb8935 100644
> --- a/drivers/i2c/busses/i2c-designware-common.c
> +++ b/drivers/i2c/busses/i2c-designware-common.c
> @@ -332,7 +332,7 @@ void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev)
> }
> EXPORT_SYMBOL_GPL(i2c_dw_adjust_bus_speed);
>
> -u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
> +u32 i2c_dw_scl_hcnt(u64 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
> {
> /*
> * DesignWare I2C core doesn't seem to have solid strategy to meet
> @@ -370,7 +370,7 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
> return DIV_ROUND_CLOSEST(ic_clk * (tSYMBOL + tf), MICRO) - 3 + offset;
> }
>
> -u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
> +u32 i2c_dw_scl_lcnt(u64 ic_clk, u32 tLOW, u32 tf, int offset)
> {
> /*
> * Conditional expression:
> diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
> index 4d3a3b464ecd..aaba6f9977b6 100644
> --- a/drivers/i2c/busses/i2c-designware-core.h
> +++ b/drivers/i2c/busses/i2c-designware-core.h
> @@ -319,8 +319,8 @@ struct i2c_dw_semaphore_callbacks {
> };
>
> int i2c_dw_init_regmap(struct dw_i2c_dev *dev);
> -u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
> -u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
> +u32 i2c_dw_scl_hcnt(u64 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
> +u32 i2c_dw_scl_lcnt(u64 ic_clk, u32 tLOW, u32 tf, int offset);
> int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev);
> unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev);
> int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare);
> diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
> index 16a4cd68567c..bfa2b37fb3f7 100644
> --- a/drivers/i2c/busses/i2c-designware-master.c
> +++ b/drivers/i2c/busses/i2c-designware-master.c
> @@ -44,7 +44,7 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
> u32 sda_falling_time, scl_falling_time;
> struct i2c_timings *t = &dev->timings;
> const char *fp_str = "";
> - u32 ic_clk;
> + u64 ic_clk;
> int ret;
>
> ret = i2c_dw_acquire_lock(dev);
> --
> 2.38.1
>

--
With Best Regards,
Andy Shevchenko


2022-12-15 01:09:00

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

Hi Hanna,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on linus/master v6.1 next-20221214]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Hanna-Hawa/i2c-designware-use-u64-for-clock-freq-to-avoid-u32-multiplication-overflow/20221214-234348
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
patch link: https://lore.kernel.org/r/20221214154117.65714-1-hhhawa%40amazon.com
patch subject: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow
config: microblaze-randconfig-r022-20221214
compiler: microblaze-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/ebc1d2486302b86b3a474d0741b79be83bea0cb9
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Hanna-Hawa/i2c-designware-use-u64-for-clock-freq-to-avoid-u32-multiplication-overflow/20221214-234348
git checkout ebc1d2486302b86b3a474d0741b79be83bea0cb9
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

microblaze-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_hcnt':
drivers/i2c/busses/i2c-designware-common.c:354: undefined reference to `__udivdi3'
>> microblaze-linux-ld: drivers/i2c/busses/i2c-designware-common.c:370: undefined reference to `__udivdi3'
microblaze-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_lcnt':
drivers/i2c/busses/i2c-designware-common.c:386: undefined reference to `__udivdi3'

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.32 kB)
config (137.02 kB)
Download all attachments

2022-12-15 03:33:38

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow

Hi Hanna,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on linus/master v6.1 next-20221215]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Hanna-Hawa/i2c-designware-use-u64-for-clock-freq-to-avoid-u32-multiplication-overflow/20221214-234348
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
patch link: https://lore.kernel.org/r/20221214154117.65714-1-hhhawa%40amazon.com
patch subject: [PATCH v2 1/1] i2c: designware: use u64 for clock freq to avoid u32 multiplication overflow
config: xtensa-randconfig-m031-20221214
compiler: xtensa-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/ebc1d2486302b86b3a474d0741b79be83bea0cb9
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Hanna-Hawa/i2c-designware-use-u64-for-clock-freq-to-avoid-u32-multiplication-overflow/20221214-234348
git checkout ebc1d2486302b86b3a474d0741b79be83bea0cb9
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=xtensa SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

xtensa-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_adjust_bus_speed':
i2c-designware-common.c:(.text+0x320): undefined reference to `__udivdi3'
xtensa-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_hcnt':
i2c-designware-common.c:(.text+0x34e): undefined reference to `__udivdi3'
xtensa-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_adjust_bus_speed':
i2c-designware-common.c:(.text+0x328): undefined reference to `__udivdi3'
xtensa-linux-ld: drivers/i2c/busses/i2c-designware-common.o: in function `i2c_dw_scl_hcnt':
i2c-designware-common.c:(.text+0x372): undefined reference to `__udivdi3'
>> xtensa-linux-ld: i2c-designware-common.c:(.text+0x390): undefined reference to `__udivdi3'
xtensa-linux-ld: drivers/i2c/busses/i2c-designware-common.o:i2c-designware-common.c:(.text+0x3ba): more undefined references to `__udivdi3' follow

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.77 kB)
config (158.07 kB)
Download all attachments