[PATCH] drm: qxl: Don't clean up uninitialized fbdev framebuffer

Daniel Vetter daniel at ffwll.ch
Thu Mar 2 07:09:35 UTC 2017


On Wed, Mar 01, 2017 at 06:50:08PM -0300, Gabriel Krisman Bertazi wrote:
> Daniel Vetter <daniel at ffwll.ch> writes:
> 
> Hi Daniel, thanks again for your review.
> 
> > Hm, I bit silly that we need #ifdef here, all this stuff is meant to Just
> > Work. Can't we just fix the oops with suitable checks in the fini paths
> > instead?
> 
> Heh.  I expected someone would bring up this objection.  My rationale is
> that on the driver side, and for many drivers, fbdev emulation code is
> always executed, even if it is only calling a bunch of NOP functions on
> the drm core, which is a bit silly.  I wonder if struct drm_driver could
> have a new callback for fbdev_initialization, which we could avoid
> calling in drm_core (maybe at registering time) if FBDEV_EMULATION is
> disabled. (well, this would go a bit in the opposite direction of having
> open coded probe sequences).
> 
> Anyway, for the Oops I mentioned, can you consider the patch below,
> instead?

lgtm.
-Daniel

> 
> >
> > Also 0day has hit some oops in bochs, it might suffer from similar bugs.
> 
> I can take a look at that too.
> 
> -- >8 --
> Subject: [PATCH] drm: qxl: Don't clean up uninitialized fbdev framebuffer
> 
> If fbdev emulation is disabled, the QXL shutdown path still tries to
> clean the framebuffer, which wasn't initialized, hitting the Oops below.
> We can check for the qfb->obj element to ensure the fb was initialized,
> because the qfb always has a bo object associated with it since
> initialization time.
> 
> [   24.284684] BUG: unable to handle kernel NULL pointer dereference at 00000000000002e0
> [   24.285627] IP: mutex_lock+0x18/0x30
> [   24.286049] PGD 78cdf067
> [   24.286050] PUD 7940f067
> [   24.286344] PMD 0
> [   24.286649]
> [   24.287072] Oops: 0002 [#1] SMP
> [   24.287422] Modules linked in: qxl
> [   24.287806] CPU: 0 PID: 2328 Comm: bash Not tainted 4.10.0-rc5+ #97
> [   24.288515] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014
> [   24.289681] task: ffff88007c4c0000 task.stack: ffffc90001b58000
> [   24.290354] RIP: 0010:mutex_lock+0x18/0x30
> [   24.290812] RSP: 0018:ffffc90001b5bcb0 EFLAGS: 00010246
> [   24.291401] RAX: 0000000000000000 RBX: 00000000000002e0 RCX: 0000000000000000
> [   24.292209] RDX: ffff88007c4c0000 RSI: 0000000000000001 RDI: 00000000000002e0
> [   24.292987] RBP: ffffc90001b5bcb8 R08: fffffffffffffffe R09: 0000000000000001
> [   24.293797] R10: ffff880078d80b80 R11: 0000000000011400 R12: 0000000000000000
> [   24.294601] R13: 00000000000002e0 R14: ffffffffa0009c28 R15: 0000000000000060
> [   24.295439] FS:  00007f30e3acbb40(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
> [   24.296364] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.296997] CR2: 00000000000002e0 CR3: 0000000078c7b000 CR4: 00000000000006f0
> [   24.297813] Call Trace:
> [   24.298097]  drm_framebuffer_cleanup+0x1f/0x70
> [   24.298612]  qxl_fbdev_fini+0x68/0x90 [qxl]
> [   24.299074]  qxl_modeset_fini+0xd/0x30 [qxl]
> [   24.299562]  qxl_pci_remove+0x22/0x50 [qxl]
> [   24.300025]  pci_device_remove+0x34/0xb0
> [   24.300507]  device_release_driver_internal+0x150/0x200
> [   24.301082]  device_release_driver+0xd/0x10
> [   24.301587]  unbind_store+0x108/0x150
> [   24.301993]  drv_attr_store+0x20/0x30
> [   24.302402]  sysfs_kf_write+0x32/0x40
> [   24.302827]  kernfs_fop_write+0x108/0x190
> [   24.303269]  __vfs_write+0x23/0x120
> [   24.303678]  ? security_file_permission+0x36/0xb0
> [   24.304193]  ? rw_verify_area+0x49/0xb0
> [   24.304636]  vfs_write+0xb0/0x190
> [   24.305004]  SyS_write+0x41/0xa0
> [   24.305362]  entry_SYSCALL_64_fastpath+0x1a/0xa9
> [   24.305887] RIP: 0033:0x7f30e31d9620
> [   24.306285] RSP: 002b:00007ffc54b47e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
> [   24.307128] RAX: ffffffffffffffda RBX: 00007f30e3497600 RCX: 00007f30e31d9620
> [   24.307928] RDX: 000000000000000d RSI: 0000000000da2008 RDI: 0000000000000001
> [   24.308727] RBP: 000000000070bc60 R08: 00007f30e3498760 R09: 00007f30e3acbb40
> [   24.309504] R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000001
> [   24.310295] R13: 0000000000000000 R14: 0000000000000000 R15: 00007ffc54b47f34
> [   24.311095] Code: 0e 01 e9 7b fe ff ff 66 90 66 2e 0f 1f 84 00 00 00 00 00
> 55 48 89 e5 53 48 89 fb e8 83 e8 ff ff 65 48 8b 14 25 40 c4 00 00 31 c0 <3e>
> 48 0f b1 13 48 85 c0 74 08 48 89 df e8 66 fd ff ff 5b 5d c3
> [   24.313182] RIP: mutex_lock+0x18/0x30 RSP: ffffc90001b5bcb0
> [   24.313811] CR2: 00000000000002e0
> [   24.314208] ---[ end trace 29669c1593cae14b ]---
> 
> Signed-off-by: Gabriel Krisman Bertazi <krisman at collabora.co.uk>
> ---
>  drivers/gpu/drm/qxl/qxl_fb.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
> index 35124737666e..4d6c311e8e5e 100644
> --- a/drivers/gpu/drm/qxl/qxl_fb.c
> +++ b/drivers/gpu/drm/qxl/qxl_fb.c
> @@ -351,13 +351,16 @@ static int qxl_fbdev_destroy(struct drm_device *dev, struct qxl_fbdev *qfbdev)
>  
>  	drm_fb_helper_unregister_fbi(&qfbdev->helper);
>  
> -	if (qfb->obj) {
> +	if (qfb->obj)
>  		qxlfb_destroy_pinned_object(qfb->obj);
> -		qfb->obj = NULL;
> -	}
> +
>  	drm_fb_helper_fini(&qfbdev->helper);
>  	vfree(qfbdev->shadow);
> -	drm_framebuffer_cleanup(&qfb->base);
> +
> +	if (qfb->obj)
> +		drm_framebuffer_cleanup(&qfb->base);

btw if you're looking for more cleanup work: Embeddeding drm_framebuffer
like this is deprecated, since it wreaks the refcounting. There's comments
around the relevant functions, and iirc we also have a todo somewhere.
-Daniel

> +
> +	qfb->obj = NULL;
>  
>  	return 0;
>  }
> -- 
> 2.11.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list