* [PATCH] i2c: mxs: ensure that DMA buffers are safe for DMA
@ 2023-02-13 15:25 ` Matthias Schiffer
0 siblings, 0 replies; 4+ messages in thread
From: Matthias Schiffer @ 2023-02-13 15:25 UTC (permalink / raw)
To: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team
Cc: Nicolas Pitre, Ard Biesheuvel, Linus Walleij, linux-i2c,
linux-arm-kernel, linux-kernel, linux, Matthias Schiffer
We found that after commit 9c46929e7989
("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems"), the
PCF85063 RTC driver stopped working on i.MX28 due to regmap_bulk_read()
reading bogus data into a stack buffer. This is caused by the i2c-mxs
driver using DMA transfers even for messages without the I2C_M_DMA_SAFE
flag, and the aforementioned commit enabling vmapped stacks.
As the MXS I2C controller requires DMA for reads of >4 bytes, DMA can't be
disabled, so the issue is fixed by using i2c_get_dma_safe_msg_buf() to
create a bounce buffer when needed.
Fixes: 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems")
Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
---
drivers/i2c/busses/i2c-mxs.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index d113bed795452..e0f3b3545cfe4 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
}
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msg, uint32_t flags)
+ struct i2c_msg *msg, u8 *buf, uint32_t flags)
{
struct dma_async_tx_descriptor *desc;
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
@@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
}
/* Queue the DMA data transfer. */
- sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+ sg_init_one(&i2c->sg_io[1], buf, msg->len);
dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
DMA_DEV_TO_MEM,
@@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
/* Queue the DMA data transfer. */
sg_init_table(i2c->sg_io, 2);
sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
- sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+ sg_set_buf(&i2c->sg_io[1], buf, msg->len);
dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
DMA_MEM_TO_DEV,
@@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
int ret;
int flags;
+ u8 *dma_buf;
int use_pio = 0;
unsigned long time_left;
@@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (ret && (ret != -ENXIO))
mxs_i2c_reset(i2c);
} else {
+ dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
+ if (!dma_buf)
+ return -ENOMEM;
+
reinit_completion(&i2c->cmd_complete);
- ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
- if (ret)
+ ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
+ if (ret) {
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
return ret;
+ }
time_left = wait_for_completion_timeout(&i2c->cmd_complete,
msecs_to_jiffies(1000));
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
if (!time_left)
goto timeout;
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH] i2c: mxs: ensure that DMA buffers are safe for DMA
@ 2023-02-13 15:25 ` Matthias Schiffer
0 siblings, 0 replies; 4+ messages in thread
From: Matthias Schiffer @ 2023-02-13 15:25 UTC (permalink / raw)
To: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team
Cc: Nicolas Pitre, Ard Biesheuvel, Linus Walleij, linux-i2c,
linux-arm-kernel, linux-kernel, linux, Matthias Schiffer
We found that after commit 9c46929e7989
("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems"), the
PCF85063 RTC driver stopped working on i.MX28 due to regmap_bulk_read()
reading bogus data into a stack buffer. This is caused by the i2c-mxs
driver using DMA transfers even for messages without the I2C_M_DMA_SAFE
flag, and the aforementioned commit enabling vmapped stacks.
As the MXS I2C controller requires DMA for reads of >4 bytes, DMA can't be
disabled, so the issue is fixed by using i2c_get_dma_safe_msg_buf() to
create a bounce buffer when needed.
Fixes: 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems")
Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
---
drivers/i2c/busses/i2c-mxs.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index d113bed795452..e0f3b3545cfe4 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -171,7 +171,7 @@ static void mxs_i2c_dma_irq_callback(void *param)
}
static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msg, uint32_t flags)
+ struct i2c_msg *msg, u8 *buf, uint32_t flags)
{
struct dma_async_tx_descriptor *desc;
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
@@ -226,7 +226,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
}
/* Queue the DMA data transfer. */
- sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+ sg_init_one(&i2c->sg_io[1], buf, msg->len);
dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
DMA_DEV_TO_MEM,
@@ -259,7 +259,7 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
/* Queue the DMA data transfer. */
sg_init_table(i2c->sg_io, 2);
sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
- sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+ sg_set_buf(&i2c->sg_io[1], buf, msg->len);
dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
DMA_MEM_TO_DEV,
@@ -563,6 +563,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
int ret;
int flags;
+ u8 *dma_buf;
int use_pio = 0;
unsigned long time_left;
@@ -588,13 +589,20 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (ret && (ret != -ENXIO))
mxs_i2c_reset(i2c);
} else {
+ dma_buf = i2c_get_dma_safe_msg_buf(msg, 1);
+ if (!dma_buf)
+ return -ENOMEM;
+
reinit_completion(&i2c->cmd_complete);
- ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
- if (ret)
+ ret = mxs_i2c_dma_setup_xfer(adap, msg, dma_buf, flags);
+ if (ret) {
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
return ret;
+ }
time_left = wait_for_completion_timeout(&i2c->cmd_complete,
msecs_to_jiffies(1000));
+ i2c_put_dma_safe_msg_buf(dma_buf, msg, true);
if (!time_left)
goto timeout;
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] i2c: mxs: ensure that DMA buffers are safe for DMA
2023-02-13 15:25 ` Matthias Schiffer
@ 2023-03-16 19:47 ` Wolfram Sang
-1 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2023-03-16 19:47 UTC (permalink / raw)
To: Matthias Schiffer
Cc: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Nicolas Pitre, Ard Biesheuvel, Linus Walleij,
linux-i2c, linux-arm-kernel, linux-kernel, linux
[-- Attachment #1: Type: text/plain, Size: 865 bytes --]
On Mon, Feb 13, 2023 at 04:25:50PM +0100, Matthias Schiffer wrote:
> We found that after commit 9c46929e7989
> ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems"), the
> PCF85063 RTC driver stopped working on i.MX28 due to regmap_bulk_read()
> reading bogus data into a stack buffer. This is caused by the i2c-mxs
> driver using DMA transfers even for messages without the I2C_M_DMA_SAFE
> flag, and the aforementioned commit enabling vmapped stacks.
>
> As the MXS I2C controller requires DMA for reads of >4 bytes, DMA can't be
> disabled, so the issue is fixed by using i2c_get_dma_safe_msg_buf() to
> create a bounce buffer when needed.
>
> Fixes: 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems")
> Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Applied to for-current, thanks!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] i2c: mxs: ensure that DMA buffers are safe for DMA
@ 2023-03-16 19:47 ` Wolfram Sang
0 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2023-03-16 19:47 UTC (permalink / raw)
To: Matthias Schiffer
Cc: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Nicolas Pitre, Ard Biesheuvel, Linus Walleij,
linux-i2c, linux-arm-kernel, linux-kernel, linux
[-- Attachment #1.1: Type: text/plain, Size: 865 bytes --]
On Mon, Feb 13, 2023 at 04:25:50PM +0100, Matthias Schiffer wrote:
> We found that after commit 9c46929e7989
> ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems"), the
> PCF85063 RTC driver stopped working on i.MX28 due to regmap_bulk_read()
> reading bogus data into a stack buffer. This is caused by the i2c-mxs
> driver using DMA transfers even for messages without the I2C_M_DMA_SAFE
> flag, and the aforementioned commit enabling vmapped stacks.
>
> As the MXS I2C controller requires DMA for reads of >4 bytes, DMA can't be
> disabled, so the issue is fixed by using i2c_get_dma_safe_msg_buf() to
> create a bounce buffer when needed.
>
> Fixes: 9c46929e7989 ("ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems")
> Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Applied to for-current, thanks!
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-03-16 19:49 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-13 15:25 [PATCH] i2c: mxs: ensure that DMA buffers are safe for DMA Matthias Schiffer
2023-02-13 15:25 ` Matthias Schiffer
2023-03-16 19:47 ` Wolfram Sang
2023-03-16 19:47 ` Wolfram Sang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.