dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
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

  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).