Re: [PATCH] iio: ad_sigma_delta: Don't put SPI transfer buffer on the stack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 2019-04-14 at 13:45 +0100, Jonathan Cameron wrote:
> [External]
> 
> 
> On Tue, 9 Apr 2019 10:58:21 +0300
> Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx> wrote:
> 
> > From: Lars-Peter Clausen <lars@xxxxxxxxxx>
> > 
> > Use a heap allocated memory for the SPI transfer buffer. Using stack
> > memory
> > will not work on some architectures when using DMA.
> > 
> > Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx>
> > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx>
> 
> Yikes, surprised this one snuck in here.
> > ---
> > 
> > Note: this doesn't need a stable/fixes tag. It's more of an
> > enhancement.
> 
> Talk me through this...  Right now I think this is a bug that is going
> to cause random and extremely hard to debug problems.  I've had these
> in the past and they are really really nasty as it's random stack
> corruption.
> The nasty is not the fact it's on the stack, but the fact that it isn't
> in it's own cacheline.
> 
> So my inclination is this definitely needs stable and fixes tag.
> What am I missing?

I guess I'm not that great with discerning stuff (about whether it needs a
stable & fixes tag).
I guess I'm still in an early phase with this one.

My sentiment, is that there haven't been enough support questions about
weird issues with sigma-delta to have categorized this earlier.

But, I guess you're right. This could do with a Fixes/stable tag.

Thanks
Alex

> 
> Jonathan
> 
> > 
> >  drivers/iio/adc/ad_sigma_delta.c       | 22 +++++++++++-----------
> >  include/linux/iio/adc/ad_sigma_delta.h |  3 ++-
> >  2 files changed, 13 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/ad_sigma_delta.c
> > b/drivers/iio/adc/ad_sigma_delta.c
> > index af6cbc683214..02d9049b9218 100644
> > --- a/drivers/iio/adc/ad_sigma_delta.c
> > +++ b/drivers/iio/adc/ad_sigma_delta.c
> > @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(ad_sd_set_comm);
> >  int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int
> > reg,
> >       unsigned int size, unsigned int val)
> >  {
> > -     uint8_t *data = sigma_delta->data;
> > +     uint8_t *data = sigma_delta->reg_data;
> >       struct spi_transfer t = {
> >               .tx_buf         = data,
> >               .len            = size + 1,
> > @@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(ad_sd_write_reg);
> >  static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
> >       unsigned int reg, unsigned int size, uint8_t *val)
> >  {
> > -     uint8_t *data = sigma_delta->data;
> > +     uint8_t *data = sigma_delta->reg_data;
> >       int ret;
> >       struct spi_transfer t[] = {
> >               {
> > @@ -148,24 +148,24 @@ int ad_sd_read_reg(struct ad_sigma_delta
> > *sigma_delta,
> >  {
> >       int ret;
> > 
> > -     ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta-
> > >data);
> > +     ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta-
> > >reg_data);
> >       if (ret < 0)
> >               goto out;
> > 
> >       switch (size) {
> >       case 4:
> > -             *val = get_unaligned_be32(sigma_delta->data);
> > +             *val = get_unaligned_be32(sigma_delta->reg_data);
> >               break;
> >       case 3:
> > -             *val = (sigma_delta->data[0] << 16) |
> > -                     (sigma_delta->data[1] << 8) |
> > -                     sigma_delta->data[2];
> > +             *val = (sigma_delta->reg_data[0] << 16) |
> > +                     (sigma_delta->reg_data[1] << 8) |
> > +                     sigma_delta->reg_data[2];
> >               break;
> >       case 2:
> > -             *val = get_unaligned_be16(sigma_delta->data);
> > +             *val = get_unaligned_be16(sigma_delta->reg_data);
> >               break;
> >       case 1:
> > -             *val = sigma_delta->data[0];
> > +             *val = sigma_delta->reg_data[0];
> >               break;
> >       default:
> >               ret = -EINVAL;
> > @@ -403,12 +403,12 @@ static irqreturn_t ad_sd_trigger_handler(int irq,
> > void *p)
> >       struct iio_poll_func *pf = p;
> >       struct iio_dev *indio_dev = pf->indio_dev;
> >       struct ad_sigma_delta *sigma_delta =
> > iio_device_get_drvdata(indio_dev);
> > +     uint8_t *data = sigma_delta->buf_data;
> >       unsigned int reg_size;
> >       unsigned int data_reg;
> > -     uint8_t data[16];
> >       int ret;
> > 
> > -     memset(data, 0x00, 16);
> > +     memset(sigma_delta->buf_data, 0x00, sizeof(sigma_delta-
> > >buf_data));
> > 
> >       reg_size = indio_dev->channels[0].scan_type.realbits +
> >                       indio_dev->channels[0].scan_type.shift;
> > diff --git a/include/linux/iio/adc/ad_sigma_delta.h
> > b/include/linux/iio/adc/ad_sigma_delta.h
> > index 6e9fb1932dde..fb77b2ebe498 100644
> > --- a/include/linux/iio/adc/ad_sigma_delta.h
> > +++ b/include/linux/iio/adc/ad_sigma_delta.h
> > @@ -79,7 +79,8 @@ struct ad_sigma_delta {
> >        * DMA (thus cache coherency maintenance) requires the
> >        * transfer buffers to live in their own cache lines.
> >        */
> > -     uint8_t                         data[4] ____cacheline_aligned;
> > +     uint8_t                         reg_data[4]
> > ____cacheline_aligned;
> > +     uint8_t                         buf_data[16];
> >  };
> > 
> >  static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta
> > *sd,
> 
> 




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux