* [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
@ 2017-11-25 19:41 Chris Wilson
2017-11-25 20:21 ` ✓ Fi.CI.BAT: success for " Patchwork
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Chris Wilson @ 2017-11-25 19:41 UTC (permalink / raw)
To: intel-gfx
Cc: Chris Wilson, Lukas Wunner, Joonas Lahtinen, Daniel Vetter,
stable
As both the hotplug event and fbdev configuration run asynchronously, it
is possible for them to run concurrently. If configuration fails, we were
freeing the fbdev causing a use-after-free in the hotplug event.
<7>[ 3069.935211] [drm:intel_fb_initial_config [i915]] Not using firmware configuration
<7>[ 3069.935225] [drm:drm_setup_crtcs] looking for cmdline mode on connector 77
<7>[ 3069.935229] [drm:drm_setup_crtcs] looking for preferred mode on connector 77 0
<7>[ 3069.935233] [drm:drm_setup_crtcs] found mode 3200x1800
<7>[ 3069.935236] [drm:drm_setup_crtcs] picking CRTCs for 8192x8192 config
<7>[ 3069.935253] [drm:drm_setup_crtcs] desired mode 3200x1800 set on crtc 43 (0,0)
<7>[ 3069.935323] [drm:intelfb_create [i915]] no BIOS fb, allocating a new one
<4>[ 3069.967737] general protection fault: 0000 [#1] PREEMPT SMP
<0>[ 3069.977453] ---------------------------------
<4>[ 3069.977457] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm r8169 mei_me mii prime_numbers mei i2c_hid pinctrl_geminilake pinctrl_intel [last unloaded: i915]
<4>[ 3069.977492] CPU: 1 PID: 15414 Comm: kworker/1:0 Tainted: G U 4.14.0-CI-CI_DRM_3388+ #1
<4>[ 3069.977497] Hardware name: Intel Corp. Geminilake/GLK RVP1 DDR4 (05), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
<4>[ 3069.977508] Workqueue: events output_poll_execute
<4>[ 3069.977512] task: ffff880177734e40 task.stack: ffffc90001fe4000
<4>[ 3069.977519] RIP: 0010:__lock_acquire+0x109/0x1b60
<4>[ 3069.977523] RSP: 0018:ffffc90001fe7bb0 EFLAGS: 00010002
<4>[ 3069.977526] RAX: 6b6b6b6b6b6b6b6b RBX: 0000000000000282 RCX: 0000000000000000
<4>[ 3069.977530] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880170d4efd0
<4>[ 3069.977534] RBP: ffffc90001fe7c70 R08: 0000000000000001 R09: 0000000000000000
<4>[ 3069.977538] R10: 0000000000000000 R11: ffffffff81899609 R12: ffff880170d4efd0
<4>[ 3069.977542] R13: ffff880177734e40 R14: 0000000000000001 R15: 0000000000000000
<4>[ 3069.977547] FS: 0000000000000000(0000) GS:ffff88017fc80000(0000) knlGS:0000000000000000
<4>[ 3069.977551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
<4>[ 3069.977555] CR2: 00007f7e8b7bcf04 CR3: 0000000003e0f000 CR4: 00000000003406e0
<4>[ 3069.977559] Call Trace:
<4>[ 3069.977565] ? mark_held_locks+0x64/0x90
<4>[ 3069.977571] ? _raw_spin_unlock_irq+0x24/0x50
<4>[ 3069.977575] ? _raw_spin_unlock_irq+0x24/0x50
<4>[ 3069.977579] ? trace_hardirqs_on_caller+0xde/0x1c0
<4>[ 3069.977583] ? _raw_spin_unlock_irq+0x2f/0x50
<4>[ 3069.977588] ? finish_task_switch+0xa5/0x210
<4>[ 3069.977592] ? lock_acquire+0xaf/0x200
<4>[ 3069.977596] lock_acquire+0xaf/0x200
<4>[ 3069.977600] ? __mutex_lock+0x5e9/0x9b0
<4>[ 3069.977604] _raw_spin_lock+0x2a/0x40
<4>[ 3069.977608] ? __mutex_lock+0x5e9/0x9b0
<4>[ 3069.977612] __mutex_lock+0x5e9/0x9b0
<4>[ 3069.977616] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
<4>[ 3069.977621] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
<4>[ 3069.977625] drm_fb_helper_hotplug_event.part.19+0x16/0xa0
<4>[ 3069.977630] output_poll_execute+0x8d/0x180
<4>[ 3069.977635] process_one_work+0x22e/0x660
<4>[ 3069.977640] worker_thread+0x48/0x3a0
<4>[ 3069.977644] ? _raw_spin_unlock_irqrestore+0x4c/0x60
<4>[ 3069.977649] kthread+0x102/0x140
<4>[ 3069.977653] ? process_one_work+0x660/0x660
<4>[ 3069.977657] ? kthread_create_on_node+0x40/0x40
<4>[ 3069.977662] ret_from_fork+0x27/0x40
<4>[ 3069.977666] Code: 8d 62 f8 c3 49 81 3c 24 e0 fa 3c 82 41 be 00 00 00 00 45 0f 45 f0 83 fe 01 77 86 89 f0 49 8b 44 c4 08 48 85 c0 0f 84 76 ff ff ff <f0> ff 80 38 01 00 00 8b 1d 62 f9 e8 01 45 8b 85 b8 08 00 00 85
<1>[ 3069.977707] RIP: __lock_acquire+0x109/0x1b60 RSP: ffffc90001fe7bb0
<4>[ 3069.977712] ---[ end trace 4ad012eb3af62df7 ]---
In order to keep the dev_priv->ifbdev alive after failure, we have to
avoid the free and leave it empty until we unload the module. Then we
can use intel_fbdev_sync() to serialise the hotplug event with the
configuration. The serialisation between the two was removed in commit
934458c2c95d ("Revert "drm/i915: Fix races on fbdev""), but the use
after free is much older, commit 366e39b4d2c5 ("drm/i915: Tear down fbdev
if initialization fails")
Fixes: 366e39b4d2c5 ("drm/i915: Tear down fbdev if initialization fails")
Fixes: 934458c2c95d ("Revert "drm/i915: Fix races on fbdev"")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lukas Wunner <lukas@wunner.de>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/i915/intel_fbdev.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index b8af35187d22..ea96682568e8 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
/* Due to peculiar init order wrt to hpd handling this is separate. */
if (drm_fb_helper_initial_config(&ifbdev->helper,
- ifbdev->preferred_bpp)) {
+ ifbdev->preferred_bpp))
intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
- intel_fbdev_fini(to_i915(ifbdev->helper.dev));
- }
}
void intel_fbdev_initial_config_async(struct drm_device *dev)
@@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
- if (ifbdev)
+ if (!ifbdev)
+ return;
+
+ intel_fbdev_sync(ifbdev);
+ if (ifbdev->vma)
drm_fb_helper_hotplug_event(&ifbdev->helper);
}
--
2.15.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* ✓ Fi.CI.BAT: success for drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
@ 2017-11-25 20:21 ` Patchwork
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2017-11-25 20:21 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
== Series Details ==
Series: drm/i915/fbdev: Serialise early hotplug events with async fbdev config
URL : https://patchwork.freedesktop.org/series/34392/
State : success
== Summary ==
Series 34392v1 drm/i915/fbdev: Serialise early hotplug events with async fbdev config
https://patchwork.freedesktop.org/api/1.0/series/34392/revisions/1/mbox/
fi-bdw-5557u total:289 pass:268 dwarn:0 dfail:0 fail:0 skip:21 time:437s
fi-bdw-gvtdvm total:289 pass:265 dwarn:0 dfail:0 fail:0 skip:24 time:449s
fi-blb-e6850 total:289 pass:223 dwarn:1 dfail:0 fail:0 skip:65 time:385s
fi-bsw-n3050 total:289 pass:243 dwarn:0 dfail:0 fail:0 skip:46 time:529s
fi-bwr-2160 total:289 pass:183 dwarn:0 dfail:0 fail:0 skip:106 time:277s
fi-bxt-dsi total:289 pass:259 dwarn:0 dfail:0 fail:0 skip:30 time:503s
fi-bxt-j4205 total:289 pass:260 dwarn:0 dfail:0 fail:0 skip:29 time:502s
fi-byt-j1900 total:289 pass:254 dwarn:0 dfail:0 fail:0 skip:35 time:490s
fi-byt-n2820 total:289 pass:250 dwarn:0 dfail:0 fail:0 skip:39 time:478s
fi-elk-e7500 total:289 pass:229 dwarn:0 dfail:0 fail:0 skip:60 time:419s
fi-gdg-551 total:289 pass:178 dwarn:1 dfail:0 fail:1 skip:109 time:267s
fi-glk-1 total:289 pass:261 dwarn:0 dfail:0 fail:0 skip:28 time:543s
fi-hsw-4770 total:289 pass:262 dwarn:0 dfail:0 fail:0 skip:27 time:425s
fi-hsw-4770r total:289 pass:262 dwarn:0 dfail:0 fail:0 skip:27 time:431s
fi-ilk-650 total:289 pass:228 dwarn:0 dfail:0 fail:0 skip:61 time:425s
fi-ivb-3520m total:289 pass:260 dwarn:0 dfail:0 fail:0 skip:29 time:483s
fi-ivb-3770 total:289 pass:260 dwarn:0 dfail:0 fail:0 skip:29 time:455s
fi-kbl-7500u total:289 pass:264 dwarn:1 dfail:0 fail:0 skip:24 time:477s
fi-kbl-7560u total:289 pass:270 dwarn:0 dfail:0 fail:0 skip:19 time:531s
fi-kbl-7567u total:289 pass:269 dwarn:0 dfail:0 fail:0 skip:20 time:475s
fi-kbl-r total:289 pass:262 dwarn:0 dfail:0 fail:0 skip:27 time:530s
fi-pnv-d510 total:289 pass:222 dwarn:1 dfail:0 fail:0 skip:66 time:569s
fi-skl-6260u total:289 pass:269 dwarn:0 dfail:0 fail:0 skip:20 time:454s
fi-skl-6600u total:289 pass:262 dwarn:0 dfail:0 fail:0 skip:27 time:541s
fi-skl-6700hq total:289 pass:263 dwarn:0 dfail:0 fail:0 skip:26 time:562s
fi-skl-6700k total:289 pass:265 dwarn:0 dfail:0 fail:0 skip:24 time:508s
fi-skl-6770hq total:289 pass:269 dwarn:0 dfail:0 fail:0 skip:20 time:495s
fi-skl-gvtdvm total:289 pass:266 dwarn:0 dfail:0 fail:0 skip:23 time:454s
fi-snb-2520m total:289 pass:250 dwarn:0 dfail:0 fail:0 skip:39 time:549s
fi-snb-2600 total:289 pass:249 dwarn:0 dfail:0 fail:0 skip:40 time:411s
Blacklisted hosts:
fi-cfl-s2 total:289 pass:263 dwarn:0 dfail:0 fail:0 skip:26 time:605s
fi-cnl-y total:289 pass:262 dwarn:0 dfail:0 fail:0 skip:27 time:550s
fi-glk-dsi total:289 pass:259 dwarn:0 dfail:0 fail:0 skip:30 time:503s
b4a607bc6d5295f19d3bf15c6fb2024251dcc0ea drm-tip: 2017y-11m-25d-18h-37m-40s UTC integration manifest
2f0b27503076 drm/i915/fbdev: Serialise early hotplug events with async fbdev config
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7291/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
2017-11-25 20:21 ` ✓ Fi.CI.BAT: success for " Patchwork
@ 2017-11-25 21:03 ` Lukas Wunner
2017-11-26 9:43 ` Chris Wilson
2017-11-25 21:34 ` ✓ Fi.CI.IGT: success for " Patchwork
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Lukas Wunner @ 2017-11-25 21:03 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx, Joonas Lahtinen, Daniel Vetter, stable
On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> As both the hotplug event and fbdev configuration run asynchronously, it
> is possible for them to run concurrently. If configuration fails, we were
> freeing the fbdev causing a use-after-free in the hotplug event.
That'll teach me to muck around in this complicated driver. :-)
IIUC, the issue is that ifbdev is briefly non-NULL and the if clause
happens to be executed when it's non-NULL and it becomes NULL upon
or during execution of intel_fbdev_output_poll_changed(), is that
correct?
Wouldn't the proper solution be to set ifbdev only after configuration
was successful, i.e. somewhere at the end of intelfb_create()?
With a memory barrier in case intel_fbdev_output_poll_changed is running
on a different CPU?
> In order to keep the dev_priv->ifbdev alive after failure, we have to
> avoid the free and leave it empty until we unload the module.
Well, that seems to defeat the goal stated in the commit message of
366e39b4d2c5 to free up the memory if fbdev initialization failed.
Not that it's a big deal for me personally, just noting. :-)
Thanks,
Lukas
^ permalink raw reply [flat|nested] 12+ messages in thread
* ✓ Fi.CI.IGT: success for drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
2017-11-25 20:21 ` ✓ Fi.CI.BAT: success for " Patchwork
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
@ 2017-11-25 21:34 ` Patchwork
2017-11-26 11:49 ` Lukas Wunner
2017-11-26 12:20 ` Lukas Wunner
4 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2017-11-25 21:34 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
== Series Details ==
Series: drm/i915/fbdev: Serialise early hotplug events with async fbdev config
URL : https://patchwork.freedesktop.org/series/34392/
State : success
== Summary ==
Warning: bzip CI_DRM_3389/shard-glkb3/results31.json.bz2 wasn't in correct JSON format
Test kms_frontbuffer_tracking:
Subgroup fbc-1p-offscren-pri-shrfb-draw-render:
pass -> FAIL (shard-snb) fdo#101623
Test drv_module_reload:
Subgroup basic-reload-inject:
pass -> DMESG-WARN (shard-snb) fdo#102707
Test kms_flip:
Subgroup flip-vs-panning-vs-hang-interruptible:
pass -> DMESG-WARN (shard-snb) fdo#103821
Test kms_plane:
Subgroup plane-panning-bottom-right-pipe-b-planes:
skip -> PASS (shard-snb)
Test kms_universal_plane:
Subgroup disable-primary-vs-flip-pipe-b:
skip -> PASS (shard-snb)
Test kms_draw_crc:
Subgroup draw-method-rgb565-mmap-cpu-xtiled:
skip -> PASS (shard-snb)
fdo#101623 https://bugs.freedesktop.org/show_bug.cgi?id=101623
fdo#102707 https://bugs.freedesktop.org/show_bug.cgi?id=102707
fdo#103821 https://bugs.freedesktop.org/show_bug.cgi?id=103821
shard-hsw total:2662 pass:1535 dwarn:1 dfail:0 fail:10 skip:1116 time:9470s
shard-snb total:2662 pass:1304 dwarn:3 dfail:0 fail:13 skip:1342 time:8062s
Blacklisted hosts:
shard-apl total:2662 pass:1689 dwarn:1 dfail:0 fail:23 skip:949 time:13384s
shard-kbl total:2662 pass:1752 dwarn:50 dfail:5 fail:21 skip:834 time:10933s
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7291/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
@ 2017-11-26 9:43 ` Chris Wilson
0 siblings, 0 replies; 12+ messages in thread
From: Chris Wilson @ 2017-11-26 9:43 UTC (permalink / raw)
To: Lukas Wunner; +Cc: Daniel Vetter, intel-gfx, stable
Quoting Lukas Wunner (2017-11-25 21:03:35)
> On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> > As both the hotplug event and fbdev configuration run asynchronously, it
> > is possible for them to run concurrently. If configuration fails, we were
> > freeing the fbdev causing a use-after-free in the hotplug event.
>
> That'll teach me to muck around in this complicated driver. :-)
>
> IIUC, the issue is that ifbdev is briefly non-NULL and the if clause
> happens to be executed when it's non-NULL and it becomes NULL upon
> or during execution of intel_fbdev_output_poll_changed(), is that
> correct?
Yes.
> Wouldn't the proper solution be to set ifbdev only after configuration
> was successful, i.e. somewhere at the end of intelfb_create()?
> With a memory barrier in case intel_fbdev_output_poll_changed is running
> on a different CPU?
I was looking at if we could easily do that; trying to look at various
methods we could defer the calls back to fbdev until after it was
registered (because that is the crux of the issue imo). I didn't see
anything as easy as using the existing one-off synchronisation.
> > In order to keep the dev_priv->ifbdev alive after failure, we have to
> > avoid the free and leave it empty until we unload the module.
>
> Well, that seems to defeat the goal stated in the commit message of
> 366e39b4d2c5 to free up the memory if fbdev initialization failed.
> Not that it's a big deal for me personally, just noting. :-)
I know, but it should at least be a small bit of unused allocation, and
we already expect to pay the cost of that allocation for normal use
cases. It may be the straw that breaks the camel's back, hopefully no
one notices in the calamity. What we might do then is just pull the
struct into dev_priv under ifdef FBDEV.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
@ 2017-11-26 11:49 ` Lukas Wunner
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2017-11-26 11:49 UTC (permalink / raw)
To: Chris Wilson; +Cc: Daniel Vetter, intel-gfx, stable
On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> @@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
>
> /* Due to peculiar init order wrt to hpd handling this is separate. */
> if (drm_fb_helper_initial_config(&ifbdev->helper,
> - ifbdev->preferred_bpp)) {
> + ifbdev->preferred_bpp))
> intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
> - intel_fbdev_fini(to_i915(ifbdev->helper.dev));
> - }
> }
Hm, the race at hand would be solved by the intel_fbdev_sync() below,
or am I missing something? Still wondering why it's necessary to
leave the fbdev around...
> @@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
> {
> struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
>
> - if (ifbdev)
> + if (!ifbdev)
> + return;
> +
> + intel_fbdev_sync(ifbdev);
> + if (ifbdev->vma)
> drm_fb_helper_hotplug_event(&ifbdev->helper);
> }
This hunk looks good, as you note the synchronization was already there
but had to be reverted because I failed to notice that a "+ 1" needs to
be added to the cookie. You did a much better job than me understanding
how the async API works with 43cee314345a.
However the "if (ifbdev->vma)" looks a bit fishy, ifbdev could be NULL
(e.g. if BIOS fb was too small but intelfb_alloc() failed) so I think
this might lead to a null pointer deref. Does it make a difference
if we check for ifbdev versus ifbdev->vma? I also notice that you
added a check for ifbdev->vma with 15727ed0d944 but Daniel later
removed it with 88be58be886f.
I guess a check *is* necessary here because fbdev initialization might
have failed, but I'd just check for "if (ifbdev)".
Thanks & have a pleasant Sunday afternoon.
Lukas
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
@ 2017-11-26 11:49 ` Lukas Wunner
0 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2017-11-26 11:49 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx, Joonas Lahtinen, Daniel Vetter, stable
On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> @@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
>
> /* Due to peculiar init order wrt to hpd handling this is separate. */
> if (drm_fb_helper_initial_config(&ifbdev->helper,
> - ifbdev->preferred_bpp)) {
> + ifbdev->preferred_bpp))
> intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
> - intel_fbdev_fini(to_i915(ifbdev->helper.dev));
> - }
> }
Hm, the race at hand would be solved by the intel_fbdev_sync() below,
or am I missing something? Still wondering why it's necessary to
leave the fbdev around...
> @@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
> {
> struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
>
> - if (ifbdev)
> + if (!ifbdev)
> + return;
> +
> + intel_fbdev_sync(ifbdev);
> + if (ifbdev->vma)
> drm_fb_helper_hotplug_event(&ifbdev->helper);
> }
This hunk looks good, as you note the synchronization was already there
but had to be reverted because I failed to notice that a "+ 1" needs to
be added to the cookie. You did a much better job than me understanding
how the async API works with 43cee314345a.
However the "if (ifbdev->vma)" looks a bit fishy, ifbdev could be NULL
(e.g. if BIOS fb was too small but intelfb_alloc() failed) so I think
this might lead to a null pointer deref. Does it make a difference
if we check for ifbdev versus ifbdev->vma? I also notice that you
added a check for ifbdev->vma with 15727ed0d944 but Daniel later
removed it with 88be58be886f.
I guess a check *is* necessary here because fbdev initialization might
have failed, but I'd just check for "if (ifbdev)".
Thanks & have a pleasant Sunday afternoon.
Lukas
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-26 11:49 ` Lukas Wunner
(?)
@ 2017-11-26 11:58 ` Chris Wilson
2017-11-26 12:15 ` Lukas Wunner
-1 siblings, 1 reply; 12+ messages in thread
From: Chris Wilson @ 2017-11-26 11:58 UTC (permalink / raw)
To: Lukas Wunner; +Cc: Daniel Vetter, intel-gfx, stable
Quoting Lukas Wunner (2017-11-26 11:49:19)
> On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> > @@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
> >
> > /* Due to peculiar init order wrt to hpd handling this is separate. */
> > if (drm_fb_helper_initial_config(&ifbdev->helper,
> > - ifbdev->preferred_bpp)) {
> > + ifbdev->preferred_bpp))
> > intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
> > - intel_fbdev_fini(to_i915(ifbdev->helper.dev));
> > - }
> > }
>
> Hm, the race at hand would be solved by the intel_fbdev_sync() below,
> or am I missing something? Still wondering why it's necessary to
> leave the fbdev around...
The race is solved, but if we do free ifbdev, we can't dereference
ifbdev prior to the sync; and we store the async cookie inside ifbdev.
Bleugh. Catch 22.
>
>
> > @@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
> > {
> > struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
> >
> > - if (ifbdev)
> > + if (!ifbdev)
> > + return;
> > +
> > + intel_fbdev_sync(ifbdev);
> > + if (ifbdev->vma)
> > drm_fb_helper_hotplug_event(&ifbdev->helper);
> > }
>
> This hunk looks good, as you note the synchronization was already there
> but had to be reverted because I failed to notice that a "+ 1" needs to
> be added to the cookie. You did a much better job than me understanding
> how the async API works with 43cee314345a.
>
> However the "if (ifbdev->vma)" looks a bit fishy, ifbdev could be NULL
> (e.g. if BIOS fb was too small but intelfb_alloc() failed) so I think
> this might lead to a null pointer deref. Does it make a difference
> if we check for ifbdev versus ifbdev->vma? I also notice that you
> added a check for ifbdev->vma with 15727ed0d944 but Daniel later
> removed it with 88be58be886f.
We know that ifbdev is non-NULL and can't become NULL until fini. So
after the sync point, we want to ask the question of whether the config
was successful, for that I used to use ->fb which now replaced by ->vma.
> I guess a check *is* necessary here because fbdev initialization might
> have failed, but I'd just check for "if (ifbdev)".
ifbdev = i915->fbdev;
if (ifbdev)
intel_fbdev_sync(ifbdev);
ifbdev = i915->fbdev;
if (ifbdev)
drm_fb_helper_hotplug_event(&ifbdev->helper);
See the problem with randomly freeing ifbdev partway through and only
using a fence?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-26 11:58 ` Chris Wilson
@ 2017-11-26 12:15 ` Lukas Wunner
0 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2017-11-26 12:15 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx, Joonas Lahtinen, Daniel Vetter, stable
On Sun, Nov 26, 2017 at 11:58:43AM +0000, Chris Wilson wrote:
> Quoting Lukas Wunner (2017-11-26 11:49:19)
> > Hm, the race at hand would be solved by the intel_fbdev_sync() below,
> > or am I missing something? Still wondering why it's necessary to
> > leave the fbdev around...
>
> The race is solved, but if we do free ifbdev, we can't dereference
> ifbdev prior to the sync; and we store the async cookie inside ifbdev.
> Bleugh. Catch 22.
Right. Oh dear god! We could move the cookie into dev_priv, the
fbdev_suspend_work is also there, outside of struct intel_fbdev.
> What we might do then is just pull the struct into dev_priv under
> ifdef FBDEV.
I vaguely remember something that dev_priv deliberately only contains
a pointer to struct intel_fbdev, that it *was* embedded in dev_priv
in the past but moved out for some reason.
> > However the "if (ifbdev->vma)" looks a bit fishy, ifbdev could be NULL
> > (e.g. if BIOS fb was too small but intelfb_alloc() failed) so I think
> > this might lead to a null pointer deref. Does it make a difference
> > if we check for ifbdev versus ifbdev->vma? I also notice that you
> > added a check for ifbdev->vma with 15727ed0d944 but Daniel later
> > removed it with 88be58be886f.
>
> We know that ifbdev is non-NULL and can't become NULL until fini. So
> after the sync point, we want to ask the question of whether the config
> was successful, for that I used to use ->fb which now replaced by ->vma.
Yes if the fbdev is kept around then obviously it's fine to deref it.
Thanks,
Lukas
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
@ 2017-11-26 12:20 ` Lukas Wunner
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2017-11-26 12:20 UTC (permalink / raw)
To: Chris Wilson; +Cc: Daniel Vetter, intel-gfx, stable
On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> As both the hotplug event and fbdev configuration run asynchronously, it
> is possible for them to run concurrently. If configuration fails, we were
> freeing the fbdev causing a use-after-free in the hotplug event.
>
> <7>[ 3069.935211] [drm:intel_fb_initial_config [i915]] Not using firmware configuration
> <7>[ 3069.935225] [drm:drm_setup_crtcs] looking for cmdline mode on connector 77
> <7>[ 3069.935229] [drm:drm_setup_crtcs] looking for preferred mode on connector 77 0
> <7>[ 3069.935233] [drm:drm_setup_crtcs] found mode 3200x1800
> <7>[ 3069.935236] [drm:drm_setup_crtcs] picking CRTCs for 8192x8192 config
> <7>[ 3069.935253] [drm:drm_setup_crtcs] desired mode 3200x1800 set on crtc 43 (0,0)
> <7>[ 3069.935323] [drm:intelfb_create [i915]] no BIOS fb, allocating a new one
> <4>[ 3069.967737] general protection fault: 0000 [#1] PREEMPT SMP
> <0>[ 3069.977453] ---------------------------------
> <4>[ 3069.977457] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm r8169 mei_me mii prime_numbers mei i2c_hid pinctrl_geminilake pinctrl_intel [last unloaded: i915]
> <4>[ 3069.977492] CPU: 1 PID: 15414 Comm: kworker/1:0 Tainted: G U 4.14.0-CI-CI_DRM_3388+ #1
> <4>[ 3069.977497] Hardware name: Intel Corp. Geminilake/GLK RVP1 DDR4 (05), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
> <4>[ 3069.977508] Workqueue: events output_poll_execute
> <4>[ 3069.977512] task: ffff880177734e40 task.stack: ffffc90001fe4000
> <4>[ 3069.977519] RIP: 0010:__lock_acquire+0x109/0x1b60
> <4>[ 3069.977523] RSP: 0018:ffffc90001fe7bb0 EFLAGS: 00010002
> <4>[ 3069.977526] RAX: 6b6b6b6b6b6b6b6b RBX: 0000000000000282 RCX: 0000000000000000
> <4>[ 3069.977530] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880170d4efd0
> <4>[ 3069.977534] RBP: ffffc90001fe7c70 R08: 0000000000000001 R09: 0000000000000000
> <4>[ 3069.977538] R10: 0000000000000000 R11: ffffffff81899609 R12: ffff880170d4efd0
> <4>[ 3069.977542] R13: ffff880177734e40 R14: 0000000000000001 R15: 0000000000000000
> <4>[ 3069.977547] FS: 0000000000000000(0000) GS:ffff88017fc80000(0000) knlGS:0000000000000000
> <4>[ 3069.977551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> <4>[ 3069.977555] CR2: 00007f7e8b7bcf04 CR3: 0000000003e0f000 CR4: 00000000003406e0
> <4>[ 3069.977559] Call Trace:
> <4>[ 3069.977565] ? mark_held_locks+0x64/0x90
> <4>[ 3069.977571] ? _raw_spin_unlock_irq+0x24/0x50
> <4>[ 3069.977575] ? _raw_spin_unlock_irq+0x24/0x50
> <4>[ 3069.977579] ? trace_hardirqs_on_caller+0xde/0x1c0
> <4>[ 3069.977583] ? _raw_spin_unlock_irq+0x2f/0x50
> <4>[ 3069.977588] ? finish_task_switch+0xa5/0x210
> <4>[ 3069.977592] ? lock_acquire+0xaf/0x200
> <4>[ 3069.977596] lock_acquire+0xaf/0x200
> <4>[ 3069.977600] ? __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977604] _raw_spin_lock+0x2a/0x40
> <4>[ 3069.977608] ? __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977612] __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977616] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977621] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977625] drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977630] output_poll_execute+0x8d/0x180
> <4>[ 3069.977635] process_one_work+0x22e/0x660
> <4>[ 3069.977640] worker_thread+0x48/0x3a0
> <4>[ 3069.977644] ? _raw_spin_unlock_irqrestore+0x4c/0x60
> <4>[ 3069.977649] kthread+0x102/0x140
> <4>[ 3069.977653] ? process_one_work+0x660/0x660
> <4>[ 3069.977657] ? kthread_create_on_node+0x40/0x40
> <4>[ 3069.977662] ret_from_fork+0x27/0x40
> <4>[ 3069.977666] Code: 8d 62 f8 c3 49 81 3c 24 e0 fa 3c 82 41 be 00 00 00 00 45 0f 45 f0 83 fe 01 77 86 89 f0 49 8b 44 c4 08 48 85 c0 0f 84 76 ff ff ff <f0> ff 80 38 01 00 00 8b 1d 62 f9 e8 01 45 8b 85 b8 08 00 00 85
> <1>[ 3069.977707] RIP: __lock_acquire+0x109/0x1b60 RSP: ffffc90001fe7bb0
> <4>[ 3069.977712] ---[ end trace 4ad012eb3af62df7 ]---
>
> In order to keep the dev_priv->ifbdev alive after failure, we have to
> avoid the free and leave it empty until we unload the module. Then we
> can use intel_fbdev_sync() to serialise the hotplug event with the
> configuration. The serialisation between the two was removed in commit
> 934458c2c95d ("Revert "drm/i915: Fix races on fbdev""), but the use
> after free is much older, commit 366e39b4d2c5 ("drm/i915: Tear down fbdev
> if initialization fails")
>
> Fixes: 366e39b4d2c5 ("drm/i915: Tear down fbdev if initialization fails")
> Fixes: 934458c2c95d ("Revert "drm/i915: Fix races on fbdev"")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lukas Wunner <lukas@wunner.de>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: stable@vger.kernel.org
Patch looks correct to me, though keeping the ifbdev around even if it
failed to initialize is regrettable. FWIW,
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Thanks,
Lukas
> ---
> drivers/gpu/drm/i915/intel_fbdev.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index b8af35187d22..ea96682568e8 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
>
> /* Due to peculiar init order wrt to hpd handling this is separate. */
> if (drm_fb_helper_initial_config(&ifbdev->helper,
> - ifbdev->preferred_bpp)) {
> + ifbdev->preferred_bpp))
> intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
> - intel_fbdev_fini(to_i915(ifbdev->helper.dev));
> - }
> }
>
> void intel_fbdev_initial_config_async(struct drm_device *dev)
> @@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
> {
> struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
>
> - if (ifbdev)
> + if (!ifbdev)
> + return;
> +
> + intel_fbdev_sync(ifbdev);
> + if (ifbdev->vma)
> drm_fb_helper_hotplug_event(&ifbdev->helper);
> }
>
> --
> 2.15.0
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
@ 2017-11-26 12:20 ` Lukas Wunner
0 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2017-11-26 12:20 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx, Joonas Lahtinen, Daniel Vetter, stable
On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> As both the hotplug event and fbdev configuration run asynchronously, it
> is possible for them to run concurrently. If configuration fails, we were
> freeing the fbdev causing a use-after-free in the hotplug event.
>
> <7>[ 3069.935211] [drm:intel_fb_initial_config [i915]] Not using firmware configuration
> <7>[ 3069.935225] [drm:drm_setup_crtcs] looking for cmdline mode on connector 77
> <7>[ 3069.935229] [drm:drm_setup_crtcs] looking for preferred mode on connector 77 0
> <7>[ 3069.935233] [drm:drm_setup_crtcs] found mode 3200x1800
> <7>[ 3069.935236] [drm:drm_setup_crtcs] picking CRTCs for 8192x8192 config
> <7>[ 3069.935253] [drm:drm_setup_crtcs] desired mode 3200x1800 set on crtc 43 (0,0)
> <7>[ 3069.935323] [drm:intelfb_create [i915]] no BIOS fb, allocating a new one
> <4>[ 3069.967737] general protection fault: 0000 [#1] PREEMPT SMP
> <0>[ 3069.977453] ---------------------------------
> <4>[ 3069.977457] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm r8169 mei_me mii prime_numbers mei i2c_hid pinctrl_geminilake pinctrl_intel [last unloaded: i915]
> <4>[ 3069.977492] CPU: 1 PID: 15414 Comm: kworker/1:0 Tainted: G U 4.14.0-CI-CI_DRM_3388+ #1
> <4>[ 3069.977497] Hardware name: Intel Corp. Geminilake/GLK RVP1 DDR4 (05), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
> <4>[ 3069.977508] Workqueue: events output_poll_execute
> <4>[ 3069.977512] task: ffff880177734e40 task.stack: ffffc90001fe4000
> <4>[ 3069.977519] RIP: 0010:__lock_acquire+0x109/0x1b60
> <4>[ 3069.977523] RSP: 0018:ffffc90001fe7bb0 EFLAGS: 00010002
> <4>[ 3069.977526] RAX: 6b6b6b6b6b6b6b6b RBX: 0000000000000282 RCX: 0000000000000000
> <4>[ 3069.977530] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880170d4efd0
> <4>[ 3069.977534] RBP: ffffc90001fe7c70 R08: 0000000000000001 R09: 0000000000000000
> <4>[ 3069.977538] R10: 0000000000000000 R11: ffffffff81899609 R12: ffff880170d4efd0
> <4>[ 3069.977542] R13: ffff880177734e40 R14: 0000000000000001 R15: 0000000000000000
> <4>[ 3069.977547] FS: 0000000000000000(0000) GS:ffff88017fc80000(0000) knlGS:0000000000000000
> <4>[ 3069.977551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> <4>[ 3069.977555] CR2: 00007f7e8b7bcf04 CR3: 0000000003e0f000 CR4: 00000000003406e0
> <4>[ 3069.977559] Call Trace:
> <4>[ 3069.977565] ? mark_held_locks+0x64/0x90
> <4>[ 3069.977571] ? _raw_spin_unlock_irq+0x24/0x50
> <4>[ 3069.977575] ? _raw_spin_unlock_irq+0x24/0x50
> <4>[ 3069.977579] ? trace_hardirqs_on_caller+0xde/0x1c0
> <4>[ 3069.977583] ? _raw_spin_unlock_irq+0x2f/0x50
> <4>[ 3069.977588] ? finish_task_switch+0xa5/0x210
> <4>[ 3069.977592] ? lock_acquire+0xaf/0x200
> <4>[ 3069.977596] lock_acquire+0xaf/0x200
> <4>[ 3069.977600] ? __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977604] _raw_spin_lock+0x2a/0x40
> <4>[ 3069.977608] ? __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977612] __mutex_lock+0x5e9/0x9b0
> <4>[ 3069.977616] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977621] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977625] drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> <4>[ 3069.977630] output_poll_execute+0x8d/0x180
> <4>[ 3069.977635] process_one_work+0x22e/0x660
> <4>[ 3069.977640] worker_thread+0x48/0x3a0
> <4>[ 3069.977644] ? _raw_spin_unlock_irqrestore+0x4c/0x60
> <4>[ 3069.977649] kthread+0x102/0x140
> <4>[ 3069.977653] ? process_one_work+0x660/0x660
> <4>[ 3069.977657] ? kthread_create_on_node+0x40/0x40
> <4>[ 3069.977662] ret_from_fork+0x27/0x40
> <4>[ 3069.977666] Code: 8d 62 f8 c3 49 81 3c 24 e0 fa 3c 82 41 be 00 00 00 00 45 0f 45 f0 83 fe 01 77 86 89 f0 49 8b 44 c4 08 48 85 c0 0f 84 76 ff ff ff <f0> ff 80 38 01 00 00 8b 1d 62 f9 e8 01 45 8b 85 b8 08 00 00 85
> <1>[ 3069.977707] RIP: __lock_acquire+0x109/0x1b60 RSP: ffffc90001fe7bb0
> <4>[ 3069.977712] ---[ end trace 4ad012eb3af62df7 ]---
>
> In order to keep the dev_priv->ifbdev alive after failure, we have to
> avoid the free and leave it empty until we unload the module. Then we
> can use intel_fbdev_sync() to serialise the hotplug event with the
> configuration. The serialisation between the two was removed in commit
> 934458c2c95d ("Revert "drm/i915: Fix races on fbdev""), but the use
> after free is much older, commit 366e39b4d2c5 ("drm/i915: Tear down fbdev
> if initialization fails")
>
> Fixes: 366e39b4d2c5 ("drm/i915: Tear down fbdev if initialization fails")
> Fixes: 934458c2c95d ("Revert "drm/i915: Fix races on fbdev"")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lukas Wunner <lukas@wunner.de>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: stable@vger.kernel.org
Patch looks correct to me, though keeping the ifbdev around even if it
failed to initialize is regrettable. FWIW,
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Thanks,
Lukas
> ---
> drivers/gpu/drm/i915/intel_fbdev.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index b8af35187d22..ea96682568e8 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -697,10 +697,8 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
>
> /* Due to peculiar init order wrt to hpd handling this is separate. */
> if (drm_fb_helper_initial_config(&ifbdev->helper,
> - ifbdev->preferred_bpp)) {
> + ifbdev->preferred_bpp))
> intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
> - intel_fbdev_fini(to_i915(ifbdev->helper.dev));
> - }
> }
>
> void intel_fbdev_initial_config_async(struct drm_device *dev)
> @@ -800,7 +798,11 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
> {
> struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
>
> - if (ifbdev)
> + if (!ifbdev)
> + return;
> +
> + intel_fbdev_sync(ifbdev);
> + if (ifbdev->vma)
> drm_fb_helper_hotplug_event(&ifbdev->helper);
> }
>
> --
> 2.15.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config
2017-11-26 12:20 ` Lukas Wunner
(?)
@ 2017-11-26 12:48 ` Chris Wilson
-1 siblings, 0 replies; 12+ messages in thread
From: Chris Wilson @ 2017-11-26 12:48 UTC (permalink / raw)
To: Lukas Wunner; +Cc: Daniel Vetter, intel-gfx, stable
Quoting Lukas Wunner (2017-11-26 12:20:32)
> On Sat, Nov 25, 2017 at 07:41:55PM +0000, Chris Wilson wrote:
> > As both the hotplug event and fbdev configuration run asynchronously, it
> > is possible for them to run concurrently. If configuration fails, we were
> > freeing the fbdev causing a use-after-free in the hotplug event.
> >
> > <7>[ 3069.935211] [drm:intel_fb_initial_config [i915]] Not using firmware configuration
> > <7>[ 3069.935225] [drm:drm_setup_crtcs] looking for cmdline mode on connector 77
> > <7>[ 3069.935229] [drm:drm_setup_crtcs] looking for preferred mode on connector 77 0
> > <7>[ 3069.935233] [drm:drm_setup_crtcs] found mode 3200x1800
> > <7>[ 3069.935236] [drm:drm_setup_crtcs] picking CRTCs for 8192x8192 config
> > <7>[ 3069.935253] [drm:drm_setup_crtcs] desired mode 3200x1800 set on crtc 43 (0,0)
> > <7>[ 3069.935323] [drm:intelfb_create [i915]] no BIOS fb, allocating a new one
> > <4>[ 3069.967737] general protection fault: 0000 [#1] PREEMPT SMP
> > <0>[ 3069.977453] ---------------------------------
> > <4>[ 3069.977457] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm r8169 mei_me mii prime_numbers mei i2c_hid pinctrl_geminilake pinctrl_intel [last unloaded: i915]
> > <4>[ 3069.977492] CPU: 1 PID: 15414 Comm: kworker/1:0 Tainted: G U 4.14.0-CI-CI_DRM_3388+ #1
> > <4>[ 3069.977497] Hardware name: Intel Corp. Geminilake/GLK RVP1 DDR4 (05), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
> > <4>[ 3069.977508] Workqueue: events output_poll_execute
> > <4>[ 3069.977512] task: ffff880177734e40 task.stack: ffffc90001fe4000
> > <4>[ 3069.977519] RIP: 0010:__lock_acquire+0x109/0x1b60
> > <4>[ 3069.977523] RSP: 0018:ffffc90001fe7bb0 EFLAGS: 00010002
> > <4>[ 3069.977526] RAX: 6b6b6b6b6b6b6b6b RBX: 0000000000000282 RCX: 0000000000000000
> > <4>[ 3069.977530] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880170d4efd0
> > <4>[ 3069.977534] RBP: ffffc90001fe7c70 R08: 0000000000000001 R09: 0000000000000000
> > <4>[ 3069.977538] R10: 0000000000000000 R11: ffffffff81899609 R12: ffff880170d4efd0
> > <4>[ 3069.977542] R13: ffff880177734e40 R14: 0000000000000001 R15: 0000000000000000
> > <4>[ 3069.977547] FS: 0000000000000000(0000) GS:ffff88017fc80000(0000) knlGS:0000000000000000
> > <4>[ 3069.977551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > <4>[ 3069.977555] CR2: 00007f7e8b7bcf04 CR3: 0000000003e0f000 CR4: 00000000003406e0
> > <4>[ 3069.977559] Call Trace:
> > <4>[ 3069.977565] ? mark_held_locks+0x64/0x90
> > <4>[ 3069.977571] ? _raw_spin_unlock_irq+0x24/0x50
> > <4>[ 3069.977575] ? _raw_spin_unlock_irq+0x24/0x50
> > <4>[ 3069.977579] ? trace_hardirqs_on_caller+0xde/0x1c0
> > <4>[ 3069.977583] ? _raw_spin_unlock_irq+0x2f/0x50
> > <4>[ 3069.977588] ? finish_task_switch+0xa5/0x210
> > <4>[ 3069.977592] ? lock_acquire+0xaf/0x200
> > <4>[ 3069.977596] lock_acquire+0xaf/0x200
> > <4>[ 3069.977600] ? __mutex_lock+0x5e9/0x9b0
> > <4>[ 3069.977604] _raw_spin_lock+0x2a/0x40
> > <4>[ 3069.977608] ? __mutex_lock+0x5e9/0x9b0
> > <4>[ 3069.977612] __mutex_lock+0x5e9/0x9b0
> > <4>[ 3069.977616] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> > <4>[ 3069.977621] ? drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> > <4>[ 3069.977625] drm_fb_helper_hotplug_event.part.19+0x16/0xa0
> > <4>[ 3069.977630] output_poll_execute+0x8d/0x180
> > <4>[ 3069.977635] process_one_work+0x22e/0x660
> > <4>[ 3069.977640] worker_thread+0x48/0x3a0
> > <4>[ 3069.977644] ? _raw_spin_unlock_irqrestore+0x4c/0x60
> > <4>[ 3069.977649] kthread+0x102/0x140
> > <4>[ 3069.977653] ? process_one_work+0x660/0x660
> > <4>[ 3069.977657] ? kthread_create_on_node+0x40/0x40
> > <4>[ 3069.977662] ret_from_fork+0x27/0x40
> > <4>[ 3069.977666] Code: 8d 62 f8 c3 49 81 3c 24 e0 fa 3c 82 41 be 00 00 00 00 45 0f 45 f0 83 fe 01 77 86 89 f0 49 8b 44 c4 08 48 85 c0 0f 84 76 ff ff ff <f0> ff 80 38 01 00 00 8b 1d 62 f9 e8 01 45 8b 85 b8 08 00 00 85
> > <1>[ 3069.977707] RIP: __lock_acquire+0x109/0x1b60 RSP: ffffc90001fe7bb0
> > <4>[ 3069.977712] ---[ end trace 4ad012eb3af62df7 ]---
> >
> > In order to keep the dev_priv->ifbdev alive after failure, we have to
> > avoid the free and leave it empty until we unload the module. Then we
> > can use intel_fbdev_sync() to serialise the hotplug event with the
> > configuration. The serialisation between the two was removed in commit
> > 934458c2c95d ("Revert "drm/i915: Fix races on fbdev""), but the use
> > after free is much older, commit 366e39b4d2c5 ("drm/i915: Tear down fbdev
> > if initialization fails")
> >
> > Fixes: 366e39b4d2c5 ("drm/i915: Tear down fbdev if initialization fails")
> > Fixes: 934458c2c95d ("Revert "drm/i915: Fix races on fbdev"")
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Lukas Wunner <lukas@wunner.de>
> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: stable@vger.kernel.org
>
> Patch looks correct to me, though keeping the ifbdev around even if it
> failed to initialize is regrettable.
Add a note to say this is decidedly not ideal.
> FWIW,
>
> Reviewed-by: Lukas Wunner <lukas@wunner.de>
Much appreciated, thanks for taking the time to dig through this code
again.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-11-26 12:48 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-25 19:41 [PATCH] drm/i915/fbdev: Serialise early hotplug events with async fbdev config Chris Wilson
2017-11-25 20:21 ` ✓ Fi.CI.BAT: success for " Patchwork
2017-11-25 21:03 ` [PATCH] " Lukas Wunner
2017-11-26 9:43 ` Chris Wilson
2017-11-25 21:34 ` ✓ Fi.CI.IGT: success for " Patchwork
2017-11-26 11:49 ` [PATCH] " Lukas Wunner
2017-11-26 11:49 ` Lukas Wunner
2017-11-26 11:58 ` Chris Wilson
2017-11-26 12:15 ` Lukas Wunner
2017-11-26 12:20 ` Lukas Wunner
2017-11-26 12:20 ` Lukas Wunner
2017-11-26 12:48 ` Chris Wilson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.