From: Stefan Agner <stefan@agner.ch>
To: Philipp Zabel <p.zabel@pengutronix.de>
Cc: linux@armlinux.org.uk, dri-devel@lists.freedesktop.org
Subject: Re: drm/imx: Crash in drm_mode_config_cleanup
Date: Thu, 13 Sep 2018 09:52:00 -0700 [thread overview]
Message-ID: <8e0763c1b5b84ac1fc94d7d430a1461b@agner.ch> (raw)
In-Reply-To: <1536827785.3452.2.camel@pengutronix.de>
Hi Philipp,
On 13.09.2018 01:36, Philipp Zabel wrote:
> Hi Stefan,
>
> thank you for the report. I think what happens is the following:
Thanks for looking into it!
>
> On Wed, 2018-09-12 at 15:26 -0700, Stefan Agner wrote:
>> Hi,
>>
>> While working on Apalis iMX6 with four displays, I encountered the
>> following crash:
>>
> [...]
>> [ 3.781163] imx-drm display-subsystem: bound 120000.hdmi (ops dw_hdmi_imx_ops)
>> [ 3.788441] imx-drm display-subsystem: binding ldb (ops imx_ldb_ops)
>> [ 3.794902] imx_ldb_bind, imx_ldb ec0da010
>
> component_bind calls devres_open_group right before component->ops->bind
>
> The devmem_kzalloc'ed imx_ldb_channel that contains the encoder is
> allocated in this devres group.
>
>> [ 3.799818] drm_encoder_init, encoder ec0da388
>> [ 3.804363] drm_encoder_init, ret 0
>
> drm_encoder_init adds the encoder in imx_ldb to the
> mode_config.encoder_list.
>
>> [ 3.807908] imx_ldb_register, encoder ec0da388
>> [ 3.812432] imx_ldb_register, ret 0
>> [ 3.815951] imx_ldb_bind encoder LVDS-46, ec0da388 ->func c0e6371c
>> [ 3.822227] imx_ldb_bind, done
>> [ 3.825331] imx-drm display-subsystem: bound ldb (ops imx_ldb_ops)
>> [ 3.831614] imx-drm display-subsystem: binding parallel-display-controller1 (ops imx_pd_ops)
>> [ 3.840285] drm_encoder_init, encoder ec8a2b78
>> [ 3.844931] imx-drm display-subsystem: Linked as a consumer to panel
>> [ 3.851472] imx-drm display-subsystem: bound parallel-display-controller1 (ops imx_pd_ops)
>> [ 3.859785] imx-drm display-subsystem: binding parallel-display-controller0 (ops imx_pd_ops)
>> [ 3.868561] imx-drm display-subsystem: failed to bind parallel-display-controller0 (ops imx_pd_ops): -517
>> [ 3.878225] imx-drm display-subsystem: Dropping the link to panel
>> [ 3.884679] imx_ldb_unbind
>> [ 3.887421] imx_ldb_unbind, encoder LVDS-46, ec0da388 ->func c0e6371c
>> [ 3.893950] imx_ldb_unbind, encoder (null), ec0da838 ->func 0
>> [ 3.899723] imx_ldb_unbind, done
>
> component_unbind calls devres_release_group after component->ops-
>>unbind, freeing imx_ldb and with it the encoder that is still in the
> mode_config.encoder_list
Oh I see, I did not realize that component_unbind releases devres...
>
>> [ 3.908345] imx_drm_bind, component_bind_all, ret -517
>> [ 3.913638] drm_mode_config_cleanup, encoder TMDS-44, ec861894 ->funcs c0e63a18
>> [ 3.921260] drm_mode_config_cleanup, calling encoder->funcs->destroy!
>> [ 3.927897] drm_encoder_cleanup, encoder ec861894
>> [ 3.932717] drm_mode_config_cleanup, encoder (null), ec0da388 ->funcs 0
>
> Use after free.
>
That all makes sense now...
>> [ 3.939356] drm_mode_config_cleanup, calling encoder->funcs->destroy!
>> [ 3.946050] Unable to handle kernel NULL pointer dereference at virtual address 00000004
> [...]
>> The Apalis iMX6 device tree I work with uses a dumb VGA bridge and a LVDS
>> display directly specified in the ldb node. In the case above I did not
>> compile in the dumb VGA bridge driver, that is the reason why binding
>> parallel-display-controller0 fails.
>
> I suppose this means that component drivers must not allocate the
> encoder in the component devres group during bind. Not only their own
> failure, but any other component's failure can cause component_unbind to
> be called in the cleanup path of component_bind_all, freeing the memory
> before drm_mode_config_cleanup is called.
>
Indeed, moving allocation into driver bind fixes the crash!
I wonder, how does devres knows that imx_ldb got allocated in probe and does not free on unbind? I guess that is the group mechanism which makes sure of that?
ldb would not the only driver affected, also drivers/gpu/drm/imx/parallel-display.c allocates encoders in component bind, there are probably more.
Actually, when thinking more about it, if we would have a way to call framework cleanup functions (drm_mode_config_cleanup() in this case) between the bind and unbind loops in component_bind_all(), we would not have that problem.
[adding Russel, since he introduced the component infrastructure]
>> The LVDS encoder (0xec1a0388 in that case) is somehow already cleaned up
>> when calling drm_mode_config_cleanup(), which leads to a null pointer
>> deference when trying to call destroy.
>>
>> I was unable to figure out why the DRM encoder in the second
>> drm_mode_config_cleanup() call is already zeroed out. The component
>> framework calls imx_ldb_unbind() first, but that should not free
>> up the encoder afaict. Any idea?
>>
>> I was also wondering in the deferred probing case, functions like
>> imx_ldb_bind() call devm_kzalloc on every try. Since the underlying
>> device is not removed, doesn't this leads to multiple active allocations?
>
> See above. To me it looks like we have to allocate imx_ldb in probe and
> deal with possibly partially preinitialzied structure when bind is
> called a second time.
>
Yeah with the fact that component framework does free devres at unbind time, my concern stated here is null...
--
Stefan
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2018-09-13 16:52 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-12 22:26 drm/imx: Crash in drm_mode_config_cleanup Stefan Agner
2018-09-13 0:31 ` Stefan Agner
2018-09-13 8:36 ` Philipp Zabel
2018-09-13 16:52 ` Stefan Agner [this message]
2019-04-02 13:49 ` [PATCH 0/3] Fix for drm_mode_config_cleanup issue Michael Grzeschik
2019-04-02 13:49 ` [PATCH 1/3] ipuv3-crtc: add remove action for devres data Michael Grzeschik
2019-04-02 15:49 ` Philipp Zabel
2019-04-03 7:22 ` Daniel Vetter
2019-04-02 13:49 ` [PATCH 2/3] ipuv3-ldb: add init list head on bind Michael Grzeschik
2019-04-02 13:49 ` [PATCH 3/3] ipuv3-ldb: add remove action for devres data Michael Grzeschik
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=8e0763c1b5b84ac1fc94d7d430a1461b@agner.ch \
--to=stefan@agner.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux@armlinux.org.uk \
--cc=p.zabel@pengutronix.de \
/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;
as well as URLs for NNTP newsgroup(s).