drm: bochs: Prevent double-free of fb helper
If fbdev registration fails for whatever reason, the error path of
bochs_fbdev_init() will call bochs_fbdev_fini(), but since an fbdev
initialization error is not fatal to the probe function, a subsequent
device removal will try to call bochs_fbdev_fini() again, hitting the
Oops below.
This was detected by 0-day with a failing framebuffer registration and
CONFIG_DEBUG_TEST_DRIVER_REMOVE=y. This reproduces the scenario I
mentioned above at insmod time, because the test attempts to remove the
device right after probing.
root@debian:~# insmod bochs-drm.ko
[ 17.609635] [drm] Found bochs VGA, ID 0xb0c0.
[ 17.612974] [drm] Framebuffer size 16384 kB @ 0xfa000000, mmio @ 0xfebf2000.
[ 17.613938] [TTM] Zone kernel: Available graphics memory:
1022244 kiB
[ 17.614701] [TTM] Initializing pool allocator
[ 17.615427] [TTM] Initializing DMA pool allocator
[ 17.619143] fbcon: bochsdrmfb (fb0) is primary device
[ 17.619428] Console: switching to colour frame buffer device 128x48
[ 17.621047] bochs-drm 0000:00:02.0: fb0: bochsdrmfb frame buffer device
[ 17.641111] [drm] Initialized bochs-drm 1.0.0
20130925 for 0000:00:02.0 on minor 0
[ 17.642380] general protection fault: 0000 [#1] SMP
[ 17.642985] Modules linked in: bochs_drm(+)
[ 17.643259] CPU: 4 PID: 3279 Comm: insmod Tainted: G W 4.11.0-rc1+ #119
[ 17.643259] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014
[ 17.643259] task:
ffff88007af35e00 task.stack:
ffffc90000d84000
[ 17.643259] RIP: 0010:drm_fb_helper_fini+0x8e/0x110
[ 17.643259] RSP: 0018:
ffffc90000d87ad0 EFLAGS:
00010202
[ 17.643259] RAX:
dead000000000200 RBX:
ffff8800790d5770 RCX:
0000000000000000
[ 17.652101] RDX:
dead000000000100 RSI:
000000007fffffff RDI:
ffffffff81eaf820
[ 17.652101] RBP:
ffffc90000d87ae0 R08:
0000000000000000 R09:
ffff88007271d918
[ 17.652101] R10:
ffffc90000d87a88 R11:
0000000000000000 R12:
0000000000000000
[ 17.652101] R13:
ffff8800790d56d0 R14:
0000000000000000 R15:
0000000000000000
[ 17.652101] FS:
00007f9285995700(0000) GS:
ffff88007cf00000(0000) knlGS:
0000000000000000
[ 17.652101] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 17.652101] CR2:
0000564f1cf9f1e8 CR3:
0000000079686000 CR4:
00000000000006e0
[ 17.652101] Call Trace:
[ 17.652101] bochs_fbdev_fini+0x24/0x90 [bochs_drm]
[ 17.652101] bochs_unload+0x16/0x50 [bochs_drm]
[ 17.652101] drm_dev_unregister+0x37/0xd0
[ 17.652101] drm_put_dev+0x31/0x60
[ 17.652101] bochs_pci_remove+0x10/0x20 [bochs_drm]
[ 17.652101] pci_device_remove+0x34/0xb0
[ 17.652101] driver_probe_device+0xd0/0x370
[ 17.652101] __driver_attach+0x96/0xa0
[ 17.652101] ? driver_probe_device+0x370/0x370
[ 17.652101] bus_for_each_dev+0x5b/0x90
[ 17.652101] driver_attach+0x19/0x20
[ 17.652101] bus_add_driver+0x11c/0x220
[ 17.652101] driver_register+0x5b/0xd0
[ 17.652101] ? 0xffffffffa0006000
[ 17.652101] __pci_register_driver+0x47/0x50
[ 17.652101] drm_pci_init+0xe1/0xf0
[ 17.652101] ? 0xffffffffa0006000
[ 17.652101] bochs_init+0x3c/0x1000 [bochs_drm]
[ 17.652101] do_one_initcall+0x3e/0x180
[ 17.652101] ? kmem_cache_alloc_trace+0x33/0x150
[ 17.652101] do_init_module+0x5a/0x1eb
[ 17.652101] load_module+0x1ea0/0x2650
[ 17.652101] ? __symbol_put+0x40/0x40
[ 17.652101] ? kernel_read_file+0x19e/0x1c0
[ 17.652101] ? kernel_read_file_from_fd+0x44/0x70
[ 17.652101] SYSC_finit_module+0xba/0xc0
[ 17.652101] SyS_finit_module+0x9/0x10
[ 17.652101] entry_SYSCALL_64_fastpath+0x1a/0xa9
[ 17.652101] RIP: 0033:0x7f92854da119
[ 17.652101] RSP: 002b:
00007ffcd0390498 EFLAGS:
00000246 ORIG_RAX:
0000000000000139
[ 17.652101] RAX:
ffffffffffffffda RBX:
00007f928578eb58 RCX:
00007f92854da119
[ 17.652101] RDX:
0000000000000000 RSI:
0000564f1c8bd638 RDI:
0000000000000003
[ 17.652101] RBP:
000000000000270e R08:
0000000000000000 R09:
00007f9285790ea0
[ 17.652101] R10:
0000000000000003 R11:
0000000000000246 R12:
00007f928578eb58
[ 17.652101] R13:
0000000000001020 R14:
0000564f1cf9e1c0 R15:
00007f928578eb00
[ 17.652101] Code: c7 20 f8 ea 81 e8 b3 3e 50 00 48 8b 83 d0 00 00 00 48 8d 93 d0 00 00 00 48 39 c2 74 46 48 8b 83 d8 00 00 00 48 8b 93 d0 00 00 00 <48> 89 42 08 48 89 10 48 b8 00 01 00 00 0000 ad de 48 89 83 d0
[ 17.652101] RIP: drm_fb_helper_fini+0x8e/0x110 RSP:
ffffc90000d87ad0
[ 17.653331] ---[ end trace
542fd75a2e60a6a4 ]---
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170324045444.11912-1-krisman@collabora.co.uk
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>