This is a note to let you know that I've just added the patch titled
iio: adc: ad7173: fix using shared static info struct
to my char-misc git tree which can be found at git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git in the char-misc-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From 36a44e05cd807a54e5ffad4b96d0d67f68ad8576 Mon Sep 17 00:00:00 2001 From: David Lechner dlechner@baylibre.com Date: Wed, 27 Nov 2024 14:01:53 -0600 Subject: iio: adc: ad7173: fix using shared static info struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
Fix a possible race condition during driver probe in the ad7173 driver due to using a shared static info struct. If more that one instance of the driver is probed at the same time, some of the info could be overwritten by the other instance, leading to incorrect operation.
To fix this, make the static info struct const so that it is read-only and make a copy of the info struct for each instance of the driver that can be modified.
Reported-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Fixes: 76a1e6a42802 ("iio: adc: ad7173: add AD7173 driver") Signed-off-by: David Lechner dlechner@baylibre.com Tested-by: Guillaume Ranquet granquet@baylibre.com Link: https://patch.msgid.link/20241127-iio-adc-ad7313-fix-non-const-info-struct-v... Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com --- drivers/iio/adc/ad7173.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 8a0c931ca83a..8b03c1e5567e 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -200,6 +200,7 @@ struct ad7173_channel {
struct ad7173_state { struct ad_sigma_delta sd; + struct ad_sigma_delta_info sigma_delta_info; const struct ad7173_device_info *info; struct ad7173_channel *channels; struct regulator_bulk_data regulators[3]; @@ -753,7 +754,7 @@ static int ad7173_disable_one(struct ad_sigma_delta *sd, unsigned int chan) return ad_sd_write_reg(sd, AD7173_REG_CH(chan), 2, 0); }
-static struct ad_sigma_delta_info ad7173_sigma_delta_info = { +static const struct ad_sigma_delta_info ad7173_sigma_delta_info = { .set_channel = ad7173_set_channel, .append_status = ad7173_append_status, .disable_all = ad7173_disable_all, @@ -1403,7 +1404,7 @@ static int ad7173_fw_parse_device_config(struct iio_dev *indio_dev) if (ret < 0) return dev_err_probe(dev, ret, "Interrupt 'rdy' is required\n");
- ad7173_sigma_delta_info.irq_line = ret; + st->sigma_delta_info.irq_line = ret;
return ad7173_fw_parse_channel_config(indio_dev); } @@ -1436,8 +1437,9 @@ static int ad7173_probe(struct spi_device *spi) spi->mode = SPI_MODE_3; spi_setup(spi);
- ad7173_sigma_delta_info.num_slots = st->info->num_configs; - ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7173_sigma_delta_info); + st->sigma_delta_info = ad7173_sigma_delta_info; + st->sigma_delta_info.num_slots = st->info->num_configs; + ret = ad_sd_init(&st->sd, indio_dev, spi, &st->sigma_delta_info); if (ret) return ret;