From: Jonathan Cameron <jic23@kernel.org>
To: Lars-Peter Clausen <lars@metafoo.de>
Cc: Hartmut Knaack <knaack.h@gmx.de>,
Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
linux-iio@vger.kernel.org
Subject: Re: [PATCH] iio: adis_lib: Initialize trigger before requesting interrupt
Date: Sat, 17 Feb 2018 14:18:36 +0000 [thread overview]
Message-ID: <20180217141836.6303ab3a@archlinux> (raw)
In-Reply-To: <20180214144300.27550-1-lars@metafoo.de>
On Wed, 14 Feb 2018 15:43:00 +0100
Lars-Peter Clausen <lars@metafoo.de> wrote:
> The adis_probe_trigger() creates a new IIO trigger and requests an
> interrupt associated with the trigger. The interrupt uses the generic
> iio_trigger_generic_data_rdy_poll() function as its interrupt handler.
>
> Currently the driver initializes some fields of the trigger structure after
> the interrupt has been requested. But an interrupt can fire as soon as it
> has been requested. This opens up a race condition.
>
> iio_trigger_generic_data_rdy_poll() will access the trigger data structure
> and dereference the ops field. If the ops field is not yet initialized this
> will result in a NULL pointer deref.
>
> It is not expected that the device generates an interrupt at this point, so
> typically this issue did not surface unless e.g. due to a hardware
> misconfiguration (wrong interrupt number, wrong polarity, etc.).
>
> But some newer devices from the ADIS family start to generate periodic
> interrupts in their power-on reset configuration and unfortunately the
> interrupt can not be masked in the device. This makes the race condition
> much more visible and the following crash has been observed occasionally
> when booting a system using the ADIS16460.
>
> Unable to handle kernel NULL pointer dereference at virtual address 00000008
> pgd = c0004000
> [00000008] *pgd=00000000
> Internal error: Oops: 5 [#1] PREEMPT SMP ARM
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.9.0-04126-gf9739f0-dirty #257
> Hardware name: Xilinx Zynq Platform
> task: ef04f640 task.stack: ef050000
> PC is at iio_trigger_notify_done+0x30/0x68
> LR is at iio_trigger_generic_data_rdy_poll+0x18/0x20
> pc : [<c042d868>] lr : [<c042d924>] psr: 60000193
> sp : ef051bb8 ip : 00000000 fp : ef106400
> r10: c081d80a r9 : ef3bfa00 r8 : 00000087
> r7 : ef051bec r6 : 00000000 r5 : ef3bfa00 r4 : ee92ab00
> r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : ee97e400
> Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
> Control: 18c5387d Table: 0000404a DAC: 00000051
> Process swapper/0 (pid: 1, stack limit = 0xef050210)
> [<c042d868>] (iio_trigger_notify_done) from [<c0065b10>] (__handle_irq_event_percpu+0x88/0x118)
> [<c0065b10>] (__handle_irq_event_percpu) from [<c0065bbc>] (handle_irq_event_percpu+0x1c/0x58)
> [<c0065bbc>] (handle_irq_event_percpu) from [<c0065c30>] (handle_irq_event+0x38/0x5c)
> [<c0065c30>] (handle_irq_event) from [<c0068e28>] (handle_level_irq+0xa4/0x130)
> [<c0068e28>] (handle_level_irq) from [<c0064e74>] (generic_handle_irq+0x24/0x34)
> [<c0064e74>] (generic_handle_irq) from [<c021ab7c>] (zynq_gpio_irqhandler+0xb8/0x13c)
> [<c021ab7c>] (zynq_gpio_irqhandler) from [<c0064e74>] (generic_handle_irq+0x24/0x34)
> [<c0064e74>] (generic_handle_irq) from [<c0065370>] (__handle_domain_irq+0x5c/0xb4)
> [<c0065370>] (__handle_domain_irq) from [<c000940c>] (gic_handle_irq+0x48/0x8c)
> [<c000940c>] (gic_handle_irq) from [<c0013e8c>] (__irq_svc+0x6c/0xa8)
>
> To fix this make sure that the trigger is fully initialized before
> requesting the interrupt.
>
> Fixes: ccd2b52f4ac6 ("staging:iio: Add common ADIS library")
> Reported-by: Robin Getz <Robin.Getz@analog.com>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Applied to the fixes-togreg-post-rc1 branch of iio.git and marked
for stable.
Thanks,
Jonathan
> ---
> drivers/iio/imu/adis_trigger.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
> index 0dd5a381be64..457372f36791 100644
> --- a/drivers/iio/imu/adis_trigger.c
> +++ b/drivers/iio/imu/adis_trigger.c
> @@ -46,6 +46,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
> if (adis->trig == NULL)
> return -ENOMEM;
>
> + adis->trig->dev.parent = &adis->spi->dev;
> + adis->trig->ops = &adis_trigger_ops;
> + iio_trigger_set_drvdata(adis->trig, adis);
> +
> ret = request_irq(adis->spi->irq,
> &iio_trigger_generic_data_rdy_poll,
> IRQF_TRIGGER_RISING,
> @@ -54,9 +58,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
> if (ret)
> goto error_free_trig;
>
> - adis->trig->dev.parent = &adis->spi->dev;
> - adis->trig->ops = &adis_trigger_ops;
> - iio_trigger_set_drvdata(adis->trig, adis);
> ret = iio_trigger_register(adis->trig);
>
> indio_dev->trig = iio_trigger_get(adis->trig);
prev parent reply other threads:[~2018-02-17 14:18 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-14 14:43 [PATCH] iio: adis_lib: Initialize trigger before requesting interrupt Lars-Peter Clausen
2018-02-17 14:18 ` Jonathan Cameron [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180217141836.6303ab3a@archlinux \
--to=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=pmeerw@pmeerw.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox