diff mbox series

i2c: designware: fix direct modify risk in xfer

Message ID 20220816025111.3702045-1-wolfgang9277@126.com
State Changes Requested
Headers show
Series i2c: designware: fix direct modify risk in xfer | expand

Commit Message

wolfgang9277@126.com Aug. 16, 2022, 2:51 a.m. UTC
From: wolfgang huang <huangjinhui@kylinos.com>

bind two or more slave devices to master device.
while master device is process reading, dev->msgs
used as a buffer to process the read data,
while the other device uses i2c_dw_xfer to read/write,
this will directly change dev->msgs, causing the
first device reading process to crash or other confusion.

so we should to check the device status before modifying
dev->msgs and others.

[ 1244.815334]  i2c_dw_isr+0x2c8/0x5e0
[ 1244.819238]  __handle_irq_event_percpu+0x5c/0x168
[ 1244.824350]  handle_irq_event_percpu+0x1c/0x58
[ 1244.829201]  handle_irq_event+0x40/0xa0
[ 1244.833449]  handle_fasteoi_irq+0xcc/0x1b0
[ 1244.837956]  generic_handle_irq+0x24/0x38
[ 1244.842376]  __handle_domain_irq+0x5c/0xb8
[ 1244.846883]  gic_handle_irq+0x94/0x1c8
[ 1244.851043]  el1_irq+0xb8/0x140
[ 1244.854599]  arch_cpu_idle+0x10/0x18
[ 1244.858588]  do_idle+0x19c/0x260
[ 1244.862231]  cpu_startup_entry+0x20/0x28

Signed-off-by: wolfgang huang <huangjinhui@kylinos.com>
---
 drivers/i2c/busses/i2c-designware-master.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

Comments

Jarkko Nikula Aug. 17, 2022, 11:01 a.m. UTC | #1
Hi

On 8/16/22 05:51, wolfgang9277@126.com wrote:
> From: wolfgang huang <huangjinhui@kylinos.com>
> 
> bind two or more slave devices to master device.

What does this sentence mean?

> while master device is process reading, dev->msgs
> used as a buffer to process the read data,
> while the other device uses i2c_dw_xfer to read/write,
> this will directly change dev->msgs, causing the
> first device reading process to crash or other confusion.
> 
> so we should to check the device status before modifying
> dev->msgs and others.
> 
> [ 1244.815334]  i2c_dw_isr+0x2c8/0x5e0
> [ 1244.819238]  __handle_irq_event_percpu+0x5c/0x168
> [ 1244.824350]  handle_irq_event_percpu+0x1c/0x58
> [ 1244.829201]  handle_irq_event+0x40/0xa0
> [ 1244.833449]  handle_fasteoi_irq+0xcc/0x1b0
> [ 1244.837956]  generic_handle_irq+0x24/0x38
> [ 1244.842376]  __handle_domain_irq+0x5c/0xb8
> [ 1244.846883]  gic_handle_irq+0x94/0x1c8
> [ 1244.851043]  el1_irq+0xb8/0x140
> [ 1244.854599]  arch_cpu_idle+0x10/0x18
> [ 1244.858588]  do_idle+0x19c/0x260
> [ 1244.862231]  cpu_startup_entry+0x20/0x28
> 
I would like to understand this more. Like is the bus not busy wait move 
enough or if it's just masking the issue away.

Are you able to share what kind of setup you have and do you know how to 
trigger this or does it occur randomly during run?

> Signed-off-by: wolfgang huang <huangjinhui@kylinos.com>
> ---
>   drivers/i2c/busses/i2c-designware-master.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
> index 44a94b225ed8..07f7d5e2d12d 100644
> --- a/drivers/i2c/busses/i2c-designware-master.c
> +++ b/drivers/i2c/busses/i2c-designware-master.c
> @@ -557,6 +557,14 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>   
>   	pm_runtime_get_sync(dev->dev);
>   
> +	ret = i2c_dw_acquire_lock(dev);
> +	if (ret)
> +		goto done_nolock;
> +
> +	ret = i2c_dw_wait_bus_not_busy(dev);
> +	if (ret)
> +		goto done;
> +
>   	/*
>   	 * Initiate I2C message transfer when AMD NAVI GPU card is enabled,
>   	 * As it is polling based transfer mechanism, which does not support

Here a few lines below the lock is never released in case of 
MODEL_AMD_NAVI_GPU since code goes to "done_nolock" after returning from 
amd_i2c_dw_xfer_quirk().

Jarkko
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 44a94b225ed8..07f7d5e2d12d 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -557,6 +557,14 @@  i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
 	pm_runtime_get_sync(dev->dev);
 
+	ret = i2c_dw_acquire_lock(dev);
+	if (ret)
+		goto done_nolock;
+
+	ret = i2c_dw_wait_bus_not_busy(dev);
+	if (ret)
+		goto done;
+
 	/*
 	 * Initiate I2C message transfer when AMD NAVI GPU card is enabled,
 	 * As it is polling based transfer mechanism, which does not support
@@ -578,14 +586,6 @@  i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	dev->abort_source = 0;
 	dev->rx_outstanding = 0;
 
-	ret = i2c_dw_acquire_lock(dev);
-	if (ret)
-		goto done_nolock;
-
-	ret = i2c_dw_wait_bus_not_busy(dev);
-	if (ret < 0)
-		goto done;
-
 	/* Start the transfers */
 	i2c_dw_xfer_init(dev);