diff mbox series

[v2,4/4] iio: imu: adis16400: Fix buffer alignment requirements.

Message ID 20210613151039.569883-5-jic23@kernel.org (mailing list archive)
State Accepted
Headers show
Series [v2,1/4] iio: core: Introduce iio_push_to_buffers_with_ts_unaligned() | expand

Commit Message

Jonathan Cameron June 13, 2021, 3:10 p.m. UTC
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>

iio_push_to_buffers_with_timestamp() requires that the buffer
is 8 byte alignment to ensure an inserted timestamp is naturally aligned.

This requirement was not met here when burst mode is in use beause
of a leading u16. Use the new iio_push_to_buffers_with_ts_unaligned()
function that has more relaxed requirements.

It is somewhat complex to access that actual data length, but a
safe bound can be found by using scan_bytes - sizeof(timestamp) so that
is used in this path.

More efficient approaches exist, but this ensure correctness at the
cost of using a bounce buffer.

Fixes: 5075e0720d93 ("iio: imu: adis: generalize burst mode support")
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
---
 drivers/iio/imu/adis16400.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

Comments

Nuno Sa June 14, 2021, 8:25 a.m. UTC | #1
> From: Jonathan Cameron <jic23@kernel.org>
> Sent: Sunday, June 13, 2021 5:11 PM
> To: linux-iio@vger.kernel.org; Andy Shevchenko
> <andy.shevchenko@gmail.com>; Sa, Nuno <Nuno.Sa@analog.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Jan Kiszka
> <jan.kiszka@siemens.com>; Jonathan Cameron
> <Jonathan.Cameron@huawei.com>; Sa, Nuno
> <Nuno.Sa@analog.com>
> Subject: [PATCH v2 4/4] iio: imu: adis16400: Fix buffer alignment
> requirements.
> 
> [External]
> 
> From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> 
> iio_push_to_buffers_with_timestamp() requires that the buffer
> is 8 byte alignment to ensure an inserted timestamp is naturally
> aligned.
> 
> This requirement was not met here when burst mode is in use beause
> of a leading u16. Use the new
> iio_push_to_buffers_with_ts_unaligned()
> function that has more relaxed requirements.
> 
> It is somewhat complex to access that actual data length, but a
> safe bound can be found by using scan_bytes - sizeof(timestamp) so
> that
> is used in this path.
> 
> More efficient approaches exist, but this ensure correctness at the
> cost of using a bounce buffer.
> 
> Fixes: 5075e0720d93 ("iio: imu: adis: generalize burst mode support")
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Reviewed-by: Nuno Sá <nuno.sa@analog.com>
> ---
>  drivers/iio/imu/adis16400.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
> index cb8d3ffab6fc..66a83ebd3109 100644
> --- a/drivers/iio/imu/adis16400.c
> +++ b/drivers/iio/imu/adis16400.c
> @@ -648,13 +648,23 @@ static irqreturn_t
> adis16400_trigger_handler(int irq, void *p)
>  	if (ret)
>  		dev_err(&adis->spi->dev, "Failed to read data: %d\n",
> ret);
> 
> -	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
> +	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) {
>  		buffer = adis->buffer + sizeof(u16);
> -	else
> -		buffer = adis->buffer;
> +		/*
> +		 * The size here is always larger than, or equal to the
> true
> +		 * size of the channel data. This may result in a larger
> copy
> +		 * than necessary, but as the target buffer will be
> +		 * buffer->scan_bytes this will be safe.
> +		 */
> +		iio_push_to_buffers_with_ts_unaligned(indio_dev,
> buffer,
> +						      indio_dev-
> >scan_bytes - sizeof(pf->timestamp),
> +						      pf->timestamp);
> +	} else {
> +		iio_push_to_buffers_with_timestamp(indio_dev,
> +						   adis->buffer,
> +						   pf->timestamp);
> +	}
> 
> -	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
> -		pf->timestamp);
> 
>  	iio_trigger_notify_done(indio_dev->trig);
> 
> --
> 2.32.0

Reviewed-by: Nuno Sá <nuno.sa@analog.com>
diff mbox series

Patch

diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
index cb8d3ffab6fc..66a83ebd3109 100644
--- a/drivers/iio/imu/adis16400.c
+++ b/drivers/iio/imu/adis16400.c
@@ -648,13 +648,23 @@  static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 	if (ret)
 		dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
 
-	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
+	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) {
 		buffer = adis->buffer + sizeof(u16);
-	else
-		buffer = adis->buffer;
+		/*
+		 * The size here is always larger than, or equal to the true
+		 * size of the channel data. This may result in a larger copy
+		 * than necessary, but as the target buffer will be
+		 * buffer->scan_bytes this will be safe.
+		 */
+		iio_push_to_buffers_with_ts_unaligned(indio_dev, buffer,
+						      indio_dev->scan_bytes - sizeof(pf->timestamp),
+						      pf->timestamp);
+	} else {
+		iio_push_to_buffers_with_timestamp(indio_dev,
+						   adis->buffer,
+						   pf->timestamp);
+	}
 
-	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
-		pf->timestamp);
 
 	iio_trigger_notify_done(indio_dev->trig);