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
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
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
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
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
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