All of lore.kernel.org
 help / color / mirror / Atom feed
* drm/nouveau: NULL pointer deref in drm_handle_vblank() on rebind
@ 2012-05-24 18:09 Bruno Prémont
  2012-05-27 20:25 ` [PATCH] drm: do not expose vblank data before drm_vblank_init completes Marcin Slusarz
  0 siblings, 1 reply; 3+ messages in thread
From: Bruno Prémont @ 2012-05-24 18:09 UTC (permalink / raw)
  To: Ben Skeggs, dri-devel

I can easily trigger a crash in nouveau interrupt handler by unbinding
and rebinding the GPU.

The command used:
  echo $pci_device > nouveau/unbind && \
	sleep 5 && \
	echo $pci_device > nouveau/bind


Kernel is 3.4.0 with modular drm/nouveau.
GPU is NVidia nForce IGP (NV11)


Unbinding seems to work fine, display switching back to VGA text mode.
Rebinding the GPU slightly later causes the below trace:

Bruno

(analysis following below trace)

[ 1432.012832] Console: switching to colour VGA+ 80x25
[ 1432.014796] drm: unregistered panic notifier
[ 1432.014905] [drm] nouveau 0000:02:00.0: Setting dpms mode 3 on vga encoder (output 0)
[ 1432.026324] [drm] nouveau 0000:02:00.0: 0xAFD8: Parsing digital output script table
[ 1432.026611] [drm] nouveau 0000:02:00.0: Restoring VGA fonts
[ 1432.028353] [TTM] Finalizing pool allocator
[ 1432.029325] [TTM] Zone  kernel: Used memory at exit: 0 kiB
[ 1437.066950] [drm] nouveau 0000:02:00.0: Detected an NV10 generation card (0x01a000b1)
[ 1437.068909] [drm] nouveau 0000:02:00.0: Checking PRAMIN for VBIOS
[ 1437.103400] [drm] nouveau 0000:02:00.0: ... BIOS checksum invalid
[ 1437.103459] [drm] nouveau 0000:02:00.0: Checking PROM for VBIOS
[ 1437.103638] [drm] nouveau 0000:02:00.0: ... BIOS checksum invalid
[ 1437.103694] [drm] nouveau 0000:02:00.0: Checking ACPI for VBIOS
[ 1437.103859] [drm] nouveau 0000:02:00.0: ... BIOS checksum invalid
[ 1437.103915] [drm] nouveau 0000:02:00.0: Checking PCIROM for VBIOS
[ 1437.105143] [drm] nouveau 0000:02:00.0: ... appears to be valid
[ 1437.105217] [drm] nouveau 0000:02:00.0: Using VBIOS from PCIROM
[ 1437.105507] [drm] nouveau 0000:02:00.0: BMP BIOS found
[ 1437.105562] [drm] nouveau 0000:02:00.0: BMP version 5.20
[ 1437.105624] [drm] nouveau 0000:02:00.0: Bios version 03.1a.01.03
[ 1437.107663] [drm] nouveau 0000:02:00.0: MXM: no VBIOS data, nothing to do
[ 1437.109053] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 0 at offset 0xA850
[ 1437.109120] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 1 at offset 0xADC5
[ 1437.109197] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 2 at offset 0xA851
[ 1437.109268] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 3 at offset 0xADC4
[ 1437.109337] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 4 at offset 0xA875
[ 1437.109405] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 5 at offset 0xA931
[ 1437.109494] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 6 at offset 0xA876
[ 1437.109572] [drm] nouveau 0000:02:00.0: Parsing VBIOS init table 7 at offset 0xA8CC
[ 1437.109985] [TTM] Zone  kernel: Available graphics memory: 240004 kiB
[ 1437.110079] [TTM] Initializing pool allocator
[ 1437.110177] [drm] nouveau 0000:02:00.0: Detected 32MiB VRAM (unknown type)
[ 1437.110424] agpgart-nvidia 0000:00:00.0: AGP 2.0 bridge
[ 1437.110566] agpgart-nvidia 0000:00:00.0: putting AGP V2 device into 4x mode
[ 1437.110717] nouveau 0000:02:00.0: putting AGP V2 device into 4x mode
[ 1437.110783] agpgart-nvidia 0000:00:00.0: AGP 2.0 bridge
[ 1437.110865] agpgart-nvidia 0000:00:00.0: putting AGP V2 device into 4x mode
[ 1437.111010] nouveau 0000:02:00.0: putting AGP V2 device into 4x mode
[ 1437.111070] [drm] nouveau 0000:02:00.0: 32 MiB GART (aperture)
[ 1437.111233] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111298] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111363] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111427] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111489] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111551] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111613] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111676] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111737] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111800] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111862] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111924] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.111986] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112048] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112110] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112172] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112233] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112296] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112357] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112420] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[ 1437.112577] [drm] nouveau 0000:02:00.0: Saving VGA fonts
[ 1437.175978] BUG: unable to handle kernel NULL pointer dereference at   (null)
[ 1437.176134] IP: [<c1272dfc>] drm_handle_vblank+0x3c/0x1d0
[ 1437.176314] *pde = 00000000 
[ 1437.176403] Oops: 0000 [#1] 
[ 1437.176491] Modules linked in: nouveau ttm drm_kms_helper cfbcopyarea mxm_wmi wmi cfbimgblt cfbfillrect nfs lockd nfs_acl sunrpc
[ 1437.177120] 
[ 1437.177170] Pid: 1573, comm: bash Not tainted 3.4.0-jupiter-00007-g3b608b6-dirty #9 NVIDIA Corporation. nFORCE-MCP/MS-6373
[ 1437.177440] EIP: 0060:[<c1272dfc>] EFLAGS: 00010056 CPU: 0
[ 1437.177495] EIP is at drm_handle_vblank+0x3c/0x1d0
[ 1437.177549] EAX: 00000000 EBX: dbfe2cb0 ECX: 00000001 EDX: 00000000
[ 1437.177604] ESI: dbfe2cb0 EDI: feffffff EBP: dd40bf6c ESP: dd40bf18
[ 1437.177660]  DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068
[ 1437.177714] CR0: 8005003b CR2: 00000000 CR3: 1cd25000 CR4: 000007d0
[ 1437.177770] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[ 1437.177825] DR6: ffff0ff0 DR7: 00000400
[ 1437.177878] Process bash (pid: 1573, ti=dd40a000 task=dcdd9090 task.ti=dcd48000)
[ 1437.177940] Stack:
[ 1437.177987]  00000000 00000051 00000003 205b0028 dbd38cf0 00000000 c1022340 dd40bf78
[ 1437.178344]  00000000 dbd38cf0 00000000 dbfe2cb0 00000000 00000002 dd40bf78 dfa00100
[ 1437.178819]  00000002 0000007b dbfe2cb0 00000018 feffffff dd40bf78 de9da248 00000000
[ 1437.179183] Call Trace:
[ 1437.179241]  [<c1022340>] ? vmalloc_sync_all+0x130/0x130
[ 1437.179356]  [<de9da248>] nv04_vblank_crtc0_isr+0x28/0x30 [nouveau]
[ 1437.179427]  [<de971204>] nouveau_irq_handler+0x64/0x100 [nouveau]
[ 1437.179490]  [<c10721d0>] ? unmask_irq+0x20/0x20
[ 1437.179545]  [<c106ff34>] handle_irq_event_percpu+0x54/0x1f0
[ 1437.179602]  [<c10721d0>] ? unmask_irq+0x20/0x20
[ 1437.179656]  [<c10700f8>] handle_irq_event+0x28/0x40
[ 1437.179711]  [<c107222b>] handle_fasteoi_irq+0x5b/0xf0
[ 1437.179763]  <IRQ> 
[ 1437.179851]  [<c1003f9a>] ? do_IRQ+0x3a/0xb0
[ 1437.179911]  [<c14053b0>] ? common_interrupt+0x30/0x38
[ 1437.179969]  [<c10c0adc>] ? __slab_alloc.clone.68+0x4c/0x3e0
[ 1437.180005]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[ 1437.180005]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[ 1437.180005]  [<c14053b0>] ? common_interrupt+0x30/0x38
[ 1437.180005]  [<c10c1a5d>] ? __kmalloc+0x15d/0x1f0
[ 1437.180005]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[ 1437.180005]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[ 1437.180005]  [<de98e36f>] ? nouveau_display_create+0x43f/0x4e0 [nouveau]
[ 1437.180005]  [<de96af7c>] ? nouveau_card_init+0x16ac/0x1a70 [nouveau]
[ 1437.180005]  [<de969770>] ? nouveau_card_channel_fini+0x20/0x20 [nouveau]
[ 1437.180005]  [<de96b86e>] ? nouveau_load+0x3fe/0x830 [nouveau]
[ 1437.180005]  [<c1276305>] ? drm_get_pci_dev+0x135/0x260
[ 1437.180005]  [<de9f6b79>] ? nouveau_pci_probe+0xd/0xf [nouveau]
[ 1437.180005]  [<c11f70a1>] ? local_pci_probe+0x41/0xb0
[ 1437.180005]  [<c11f7560>] ? pci_device_probe+0x60/0x80
[ 1437.180005]  [<c128ec25>] ? driver_probe_device+0x75/0x1d0
[ 1437.180005]  [<c11f6f8a>] ? pci_match_device+0x9a/0xa0
[ 1437.180005]  [<c128db87>] ? driver_bind+0x97/0xe0
[ 1437.180005]  [<c128daf0>] ? driver_unbind+0x90/0x90
[ 1437.180005]  [<c128d217>] ? drv_attr_store+0x27/0x30
[ 1437.180005]  [<c1117a59>] ? sysfs_write_file+0x99/0x100
[ 1437.180005]  [<c10c95ea>] ? vfs_write+0x9a/0x140
[ 1437.180005]  [<c10d6a90>] ? sys_dup3+0xf0/0x150
[ 1437.180005]  [<c10d6f8c>] ? do_fcntl+0x36c/0x4a0
[ 1437.180005]  [<c11179c0>] ? sysfs_poll+0x90/0x90
[ 1437.180005]  [<c10c986d>] ? sys_write+0x3d/0x70
[ 1437.180005]  [<c1404e97>] ? sysenter_do_call+0x12/0x26
[ 1437.180005] Code: 00 00 89 55 cc 85 c9 0f 84 4d 01 00 00 9c 8f 45 e0 fa 89 e0 25 00 e0 ff ff ff 40 14 c1 e2 02 8b 86 58 01 00 00 89 55 dc 8b 55 cc <8b> 04 90 85 c0 0f 84 31 01 00 00 8b 45 dc 03 86 48 01 00 00 


According to objdump that would match:

bool drm_handle_vblank(struct drm_device *dev, int crtc)
{
        u32 vblcount;
        s64 diff_ns;
        struct timeval tvblank;
        unsigned long irqflags;

        if (!dev->num_crtcs)
                return false;

        /* Need timestamp lock to prevent concurrent execution with
         * vblank enable/disable, as this would cause inconsistent
         * or corrupted timestamps and vblank counts.
         */
        spin_lock_irqsave(&dev->vblank_time_lock, irqflags);

        /* Vblank irq handling disabled. Nothing to do. */
        if (!dev->vblank_enabled[crtc]) {
                spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
                return false;
        }



        /* Vblank irq handling disabled. Nothing to do. */
        if (!dev->vblank_enabled[crtc]) {
    1e1d:       c1 e2 02                shl    $0x2,%edx
    1e20:       8b 86 58 01 00 00       mov    0x158(%esi),%eax
    1e26:       89 55 dc                mov    %edx,-0x24(%ebp)
    1e29:       8b 55 cc                mov    -0x34(%ebp),%edx
>>> 1e2c:       8b 04 90                mov    (%eax,%edx,4),%eax
    1e2f:       85 c0                   test   %eax,%eax
    1e31:       0f 84 31 01 00 00       je     1f68 <drm_handle_vblank+0x178>

That means that dev->vblank_enabled is not initialized yet while IRQs are
already triggering?

I check the assumption that dev->vblank_enabled is NULL by first testing
it before trying to access [crtc] and firing a WARN_ON which indicates that
it happens 3 times untile probing of GPU completes:

[  149.017679] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[  149.017741] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[  149.017803] [drm] nouveau 0000:02:00.0: PMC - unhandled INTR 0x01000000
[  149.017956] [drm] nouveau 0000:02:00.0: Saving VGA fonts
[  149.082726] ------------[ cut here ]------------
[  149.082817] WARNING: at /usr/src/linux-git/drivers/gpu/drm/drm_irq.c:1302 drm_handle_vblank+0x1e2/0x1f0()
[  149.082884] Hardware name: nFORCE-MCP
[  149.082937] Modules linked in: nouveau ttm cfbcopyarea mxm_wmi wmi cfbimgblt cfbfillrect drm_kms_helper nfs lockd nfs_acl sunrpc
[  149.083669] Pid: 1564, comm: bash Not tainted 3.4.0-jupiter-00007-g3b608b6-dirty #10
[  149.083733] Call Trace:
[  149.083791]  [<c102a53d>] warn_slowpath_common+0x6d/0xa0
[  149.083849]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.083906]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.083963]  [<c102a58d>] warn_slowpath_null+0x1d/0x20
[  149.084018]  [<c1272fa2>] drm_handle_vblank+0x1e2/0x1f0
[  149.084078]  [<c1022340>] ? vmalloc_sync_all+0x130/0x130
[  149.084139]  [<c1404c29>] ? error_code+0x65/0x6c
[  149.084198]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.084308]  [<de9c9248>] nv04_vblank_crtc0_isr+0x28/0x30 [nouveau]
[  149.084378]  [<de960204>] nouveau_irq_handler+0x64/0x100 [nouveau]
[  149.084459]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.084598]  [<c106ff34>] handle_irq_event_percpu+0x54/0x1f0
[  149.084654]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.084708]  [<c10700f8>] handle_irq_event+0x28/0x40
[  149.084763]  [<c107222b>] handle_fasteoi_irq+0x5b/0xf0
[  149.084815]  <IRQ>  [<c1003f9a>] ? do_IRQ+0x3a/0xb0
[  149.084912]  [<c14053b0>] ? common_interrupt+0x30/0x38
[  149.084968]  [<c10c0adc>] ? __slab_alloc.clone.68+0x4c/0x3e0
[  149.085024]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.085078]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.085136]  [<c103055c>] ? irq_exit+0x5c/0xa0
[  149.085189]  [<c1003fa3>] ? do_IRQ+0x43/0xb0
[  149.085242]  [<c14053b0>] ? common_interrupt+0x30/0x38
[  149.085296]  [<c10c1a5d>] ? __kmalloc+0x15d/0x1f0
[  149.085350]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.085405]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.085475]  [<de97d36f>] ? nouveau_display_create+0x43f/0x4e0 [nouveau]
[  149.085544]  [<de959f7c>] ? nouveau_card_init+0x16ac/0x1a70 [nouveau]
[  149.085612]  [<de958770>] ? nouveau_card_channel_fini+0x20/0x20 [nouveau]
[  149.085680]  [<de95a86e>] ? nouveau_load+0x3fe/0x830 [nouveau]
[  149.085737]  [<c1276325>] ? drm_get_pci_dev+0x135/0x260
[  149.085808]  [<de9e5b79>] ? nouveau_pci_probe+0xd/0xf [nouveau]
[  149.085869]  [<c11f70a1>] ? local_pci_probe+0x41/0xb0
[  149.085924]  [<c11f7560>] ? pci_device_probe+0x60/0x80
[  149.085992]  [<c128ec45>] ? driver_probe_device+0x75/0x1d0
[  149.086047]  [<c11f6f8a>] ? pci_match_device+0x9a/0xa0
[  149.086223]  [<c128dba7>] ? driver_bind+0x97/0xe0
[  149.086278]  [<c128db10>] ? driver_unbind+0x90/0x90
[  149.086333]  [<c128d237>] ? drv_attr_store+0x27/0x30
[  149.087347]  [<c1117a59>] ? sysfs_write_file+0x99/0x100
[  149.087404]  [<c10c95ea>] ? vfs_write+0x9a/0x140
[  149.087461]  [<c10d6a90>] ? sys_dup3+0xf0/0x150
[  149.087515]  [<c10d6f8c>] ? do_fcntl+0x36c/0x4a0
[  149.087567]  [<c11179c0>] ? sysfs_poll+0x90/0x90
[  149.087621]  [<c10c986d>] ? sys_write+0x3d/0x70
[  149.087675]  [<c1404e97>] ? sysenter_do_call+0x12/0x26
[  149.087729] ---[ end trace 5d73f7bccc0ebc64 ]---
[  149.087802] ------------[ cut here ]------------
[  149.087888] WARNING: at /usr/src/linux-git/drivers/gpu/drm/drm_irq.c:1302 drm_handle_vblank+0x1e2/0x1f0()
[  149.087953] Hardware name: nFORCE-MCP
[  149.088002] Modules linked in: nouveau ttm cfbcopyarea mxm_wmi wmi cfbimgblt cfbfillrect drm_kms_helper nfs lockd nfs_acl sunrpc
[  149.088543] Pid: 1564, comm: bash Tainted: G        W    3.4.0-jupiter-00007-g3b608b6-dirty #10
[  149.088606] Call Trace:
[  149.088656]  [<c102a53d>] warn_slowpath_common+0x6d/0xa0
[  149.088710]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.088765]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.088819]  [<c102a58d>] warn_slowpath_null+0x1d/0x20
[  149.088874]  [<c1272fa2>] drm_handle_vblank+0x1e2/0x1f0
[  149.088928]  [<c1022340>] ? vmalloc_sync_all+0x130/0x130
[  149.088983]  [<c1404c29>] ? error_code+0x65/0x6c
[  149.089036]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.089110]  [<de9c9248>] nv04_vblank_crtc0_isr+0x28/0x30 [nouveau]
[  149.089178]  [<de960204>] nouveau_irq_handler+0x64/0x100 [nouveau]
[  149.089234]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.089287]  [<c106ff34>] handle_irq_event_percpu+0x54/0x1f0
[  149.089342]  [<c10721d0>] ? unmask_irq+0x20/0x20
[  149.089395]  [<c10700f8>] handle_irq_event+0x28/0x40
[  149.089449]  [<c107222b>] handle_fasteoi_irq+0x5b/0xf0
[  149.089500]  <IRQ>  [<c1003f9a>] ? do_IRQ+0x3a/0xb0
[  149.089593]  [<c14053b0>] ? common_interrupt+0x30/0x38
[  149.089651]  [<c12d7687>] ? nv_napi_poll+0xe7/0x590
[  149.089705]  [<c103055c>] ? irq_exit+0x5c/0xa0
[  149.089757]  [<c1003fa3>] ? do_IRQ+0x43/0xb0
[  149.089832]  [<c137cf2c>] ? __qdisc_run+0x4c/0x110
[  149.089889]  [<c1368328>] ? net_rx_action+0xd8/0x1b0
[  149.089943]  [<c1030275>] ? __do_softirq+0x85/0x1a0
[  149.089997]  [<c10301f0>] ? local_bh_enable_ip+0x80/0x80
[  149.090010]  <IRQ>  [<c1030576>] ? irq_exit+0x76/0xa0
[  149.090010]  [<c1003fa3>] ? do_IRQ+0x43/0xb0
[  149.090010]  [<c14053b0>] ? common_interrupt+0x30/0x38
[  149.090010]  [<c10c0adc>] ? __slab_alloc.clone.68+0x4c/0x3e0
[  149.090010]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.090010]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.090010]  [<c103055c>] ? irq_exit+0x5c/0xa0
[  149.090010]  [<c1003fa3>] ? do_IRQ+0x43/0xb0
[  149.090010]  [<c14053b0>] ? common_interrupt+0x30/0x38
[  149.090010]  [<c10c1a5d>] ? __kmalloc+0x15d/0x1f0
[  149.090010]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.090010]  [<c1271e83>] ? drm_vblank_init+0x43/0x1d0
[  149.090010]  [<de97d36f>] ? nouveau_display_create+0x43f/0x4e0 [nouveau]
[  149.090010]  [<de959f7c>] ? nouveau_card_init+0x16ac/0x1a70 [nouveau]
[  149.090010]  [<de958770>] ? nouveau_card_channel_fini+0x20/0x20 [nouveau]
[  149.090010]  [<de95a86e>] ? nouveau_load+0x3fe/0x830 [nouveau]
[  149.090010]  [<c1276325>] ? drm_get_pci_dev+0x135/0x260
[  149.090010]  [<de9e5b79>] ? nouveau_pci_probe+0xd/0xf [nouveau]
[  149.090010]  [<c11f70a1>] ? local_pci_probe+0x41/0xb0
[  149.090010]  [<c11f7560>] ? pci_device_probe+0x60/0x80
[  149.090010]  [<c128ec45>] ? driver_probe_device+0x75/0x1d0
[  149.090010]  [<c11f6f8a>] ? pci_match_device+0x9a/0xa0
[  149.090010]  [<c128dba7>] ? driver_bind+0x97/0xe0
[  149.090010]  [<c128db10>] ? driver_unbind+0x90/0x90
[  149.090010]  [<c128d237>] ? drv_attr_store+0x27/0x30
[  149.090010]  [<c1117a59>] ? sysfs_write_file+0x99/0x100
[  149.090010]  [<c10c95ea>] ? vfs_write+0x9a/0x140
[  149.090010]  [<c10d6a90>] ? sys_dup3+0xf0/0x150
[  149.090010]  [<c10d6f8c>] ? do_fcntl+0x36c/0x4a0
[  149.090010]  [<c11179c0>] ? sysfs_poll+0x90/0x90
[  149.090010]  [<c10c986d>] ? sys_write+0x3d/0x70
[  149.090010]  [<c1404e97>] ? sysenter_do_call+0x12/0x26
[  149.090010] ---[ end trace 5d73f7bccc0ebc65 ]---
[  149.097648] ------------[ cut here ]------------
[  149.097726] WARNING: at /usr/src/linux-git/drivers/gpu/drm/drm_irq.c:1302 drm_handle_vblank+0x1e2/0x1f0()
[  149.097793] Hardware name: nFORCE-MCP
[  149.097842] Modules linked in: nouveau ttm cfbcopyarea mxm_wmi wmi cfbimgblt cfbfillrect drm_kms_helper nfs lockd nfs_acl sunrpc
[  149.098398] Pid: 1835, comm: syslog-ng Tainted: G        W    3.4.0-jupiter-00007-g3b608b6-dirty #10
[  149.098463] Call Trace:
[  149.098519]  [<c102a53d>] warn_slowpath_common+0x6d/0xa0
[  149.098575]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.098632]  [<c1272fa2>] ? drm_handle_vblank+0x1e2/0x1f0
[  149.098686]  [<c102a58d>] warn_slowpath_null+0x1d/0x20
[  149.098741]  [<c1272fa2>] drm_handle_vblank+0x1e2/0x1f0
[  149.098800]  [<c1022340>] ? vmalloc_sync_all+0x130/0x130
[  149.098860]  [<c1404c29>] ? error_code+0x65/0x6c
[  149.098973]  [<de9c9248>] nv04_vblank_crtc0_isr+0x28/0x30 [nouveau]
[  149.099042]  [<de960204>] nouveau_irq_handler+0x64/0x100 [nouveau]
[  149.099103]  [<c106ff34>] handle_irq_event_percpu+0x54/0x1f0
[  149.099158]  [<c10700f8>] handle_irq_event+0x28/0x40
[  149.099214]  [<c107222b>] handle_fasteoi_irq+0x5b/0xf0
[  149.099271]  [<c1004176>] handle_irq+0x56/0xe0
[  149.099323]  [<c1003f9a>] do_IRQ+0x3a/0xb0
[  149.099380]  [<c10c986d>] ? sys_write+0x3d/0x70
[  149.099435]  [<c14053b0>] common_interrupt+0x30/0x38
[  149.099488] ---[ end trace 5d73f7bccc0ebc66 ]---
[  149.100069] [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
[  149.100130] [drm] No driver support for vblank timestamp query.
[  149.100224] [drm] nouveau 0000:02:00.0: 0 available performance level(s)
[  149.100284] [drm] nouveau 0000:02:00.0: c: core 174MHz memory 0MHz
[  149.102004] [drm] nouveau 0000:02:00.0: 0xAFD8: Parsing digital output script table
[  149.102299] [drm] nouveau 0000:02:00.0: Setting dpms mode 3 on vga encoder (output 0)
[  149.102365] [drm] nouveau 0000:02:00.0: Setting dpms mode 3 on tmds encoder (output 1)
[  149.297232] [drm] nouveau 0000:02:00.0: Load detected on head A
[  149.305870] [drm] Got external EDID base block and 0 extensions from "edid/iiyama-ProLite_E431.bin" for connector "DVI-I-2"
[  149.307904] [drm] nouveau 0000:02:00.0: allocated 1280x1024 fb: 0x45000, bo dcea6000
[  149.308177] fbcon: New framebuffer notification for fb0
[  149.308233] fbcon: nouveaufb (fb0) is primary device
[  149.308294] fbcon: info_fb unset...
[  149.319739] [drm] nouveau 0000:02:00.0: Setting dpms mode 0 on vga encoder (output 0)
[  149.319746] [drm] nouveau 0000:02:00.0: Output DVI-I-2 is running on CRTC 0 using output A
[  149.325136] Console: switching to colour frame buffer device 160x64
[  149.327824] fbcon: info_fb set, takeover = 0...
[  149.327851] fbcon: info is dcd3b4d0, info_fb is dcd3b4d0, con2fb_map[0] = dcd3b4d0, con2fb_map_boot[0] = 0
[  149.327901] fb0: nouveaufb frame buffer device
[  149.327930] drm: registered panic notifier
[  149.327967] [drm] Initialized nouveau 1.0.0 20120316 for 0000:02:00.0 on minor 0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] drm: do not expose vblank data before drm_vblank_init completes
  2012-05-24 18:09 drm/nouveau: NULL pointer deref in drm_handle_vblank() on rebind Bruno Prémont
@ 2012-05-27 20:25 ` Marcin Slusarz
  2012-06-08 21:13   ` Marcin Slusarz
  0 siblings, 1 reply; 3+ messages in thread
From: Marcin Slusarz @ 2012-05-27 20:25 UTC (permalink / raw)
  To: Bruno Prémont, Dave Airlie; +Cc: dri-devel

On Thu, May 24, 2012 at 08:09:41PM +0200, Bruno Prémont wrote:
> I can easily trigger a crash in nouveau interrupt handler by unbinding
> and rebinding the GPU.
> 
> The command used:
>   echo $pci_device > nouveau/unbind && \
> 	sleep 5 && \
> 	echo $pci_device > nouveau/bind
> 
> 
> Kernel is 3.4.0 with modular drm/nouveau.
> GPU is NVidia nForce IGP (NV11)
> 
> 
> Unbinding seems to work fine, display switching back to VGA text mode.
> Rebinding the GPU slightly later causes the below trace:
> 
> (...)

It crashed because Nouveau failed to disable vblank interrupt on unbind
and this interrupt triggered while drm was initializing vblank data.

Nouveau side was fixed by "drm/nv04/disp: disable vblank interrupts when
disabling display" by Ben Skeggs (3.5 merge window), drm side can be fixed
by this:

---
From: Marcin Slusarz <marcin.slusarz@gmail.com>
Subject: [PATCH] drm: do not expose vblank data before drm_vblank_init completes

It fixes oops in drm_handle_vblank when vblank interrupt triggers before
drm_vblank_init completes. Driver side should not let this happen, but let's
be on the safe side and handle this case.

Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
Tested-by: Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
---
 drivers/gpu/drm/drm_irq.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index c869436..7dda18c 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -183,12 +183,8 @@ static void vblank_disable_fn(unsigned long arg)
 	}
 }
 
-void drm_vblank_cleanup(struct drm_device *dev)
+static void __drm_vblank_cleanup(struct drm_device *dev)
 {
-	/* Bail if the driver didn't call drm_vblank_init() */
-	if (dev->num_crtcs == 0)
-		return;
-
 	del_timer(&dev->vblank_disable_timer);
 
 	vblank_disable_fn((unsigned long)dev);
@@ -201,6 +197,15 @@ void drm_vblank_cleanup(struct drm_device *dev)
 	kfree(dev->last_vblank_wait);
 	kfree(dev->vblank_inmodeset);
 	kfree(dev->_vblank_time);
+}
+
+void drm_vblank_cleanup(struct drm_device *dev)
+{
+	/* Bail if the driver didn't call drm_vblank_init() */
+	if (dev->num_crtcs == 0)
+		return;
+
+	__drm_vblank_cleanup(dev);
 
 	dev->num_crtcs = 0;
 }
@@ -215,8 +220,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 	spin_lock_init(&dev->vbl_lock);
 	spin_lock_init(&dev->vblank_time_lock);
 
-	dev->num_crtcs = num_crtcs;
-
 	dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs,
 				 GFP_KERNEL);
 	if (!dev->vbl_queue)
@@ -268,10 +271,12 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 	}
 
 	dev->vblank_disable_allowed = 0;
+	dev->num_crtcs = num_crtcs;
+
 	return 0;
 
 err:
-	drm_vblank_cleanup(dev);
+	__drm_vblank_cleanup(dev);
 	return ret;
 }
 EXPORT_SYMBOL(drm_vblank_init);
-- 
1.7.8.6

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] drm: do not expose vblank data before drm_vblank_init completes
  2012-05-27 20:25 ` [PATCH] drm: do not expose vblank data before drm_vblank_init completes Marcin Slusarz
@ 2012-06-08 21:13   ` Marcin Slusarz
  0 siblings, 0 replies; 3+ messages in thread
From: Marcin Slusarz @ 2012-06-08 21:13 UTC (permalink / raw)
  To: Dave Airlie; +Cc: Bruno Prémont, dri-devel

On Sun, May 27, 2012 at 10:25:21PM +0200, Marcin Slusarz wrote:
> On Thu, May 24, 2012 at 08:09:41PM +0200, Bruno Prémont wrote:
> > I can easily trigger a crash in nouveau interrupt handler by unbinding
> > and rebinding the GPU.
> > 
> > The command used:
> >   echo $pci_device > nouveau/unbind && \
> > 	sleep 5 && \
> > 	echo $pci_device > nouveau/bind
> > 
> > 
> > Kernel is 3.4.0 with modular drm/nouveau.
> > GPU is NVidia nForce IGP (NV11)
> > 
> > 
> > Unbinding seems to work fine, display switching back to VGA text mode.
> > Rebinding the GPU slightly later causes the below trace:
> > 
> > (...)
> 
> It crashed because Nouveau failed to disable vblank interrupt on unbind
> and this interrupt triggered while drm was initializing vblank data.
> 
> Nouveau side was fixed by "drm/nv04/disp: disable vblank interrupts when
> disabling display" by Ben Skeggs (3.5 merge window), drm side can be fixed
> by this:
> 
> ---
> From: Marcin Slusarz <marcin.slusarz@gmail.com>
> Subject: [PATCH] drm: do not expose vblank data before drm_vblank_init completes
> 
> It fixes oops in drm_handle_vblank when vblank interrupt triggers before
> drm_vblank_init completes. Driver side should not let this happen, but let's
> be on the safe side and handle this case.
> 
> Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
> Tested-by: Bruno Prémont <bonbons@linux-vserver.org>
> Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
> ---
>  drivers/gpu/drm/drm_irq.c |   21 +++++++++++++--------
>  1 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index c869436..7dda18c 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -183,12 +183,8 @@ static void vblank_disable_fn(unsigned long arg)
>  	}
>  }
>  
> -void drm_vblank_cleanup(struct drm_device *dev)
> +static void __drm_vblank_cleanup(struct drm_device *dev)
>  {
> -	/* Bail if the driver didn't call drm_vblank_init() */
> -	if (dev->num_crtcs == 0)
> -		return;
> -
>  	del_timer(&dev->vblank_disable_timer);
>  
>  	vblank_disable_fn((unsigned long)dev);
> @@ -201,6 +197,15 @@ void drm_vblank_cleanup(struct drm_device *dev)
>  	kfree(dev->last_vblank_wait);
>  	kfree(dev->vblank_inmodeset);
>  	kfree(dev->_vblank_time);
> +}
> +
> +void drm_vblank_cleanup(struct drm_device *dev)
> +{
> +	/* Bail if the driver didn't call drm_vblank_init() */
> +	if (dev->num_crtcs == 0)
> +		return;
> +
> +	__drm_vblank_cleanup(dev);
>  
>  	dev->num_crtcs = 0;
>  }
> @@ -215,8 +220,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
>  	spin_lock_init(&dev->vbl_lock);
>  	spin_lock_init(&dev->vblank_time_lock);
>  
> -	dev->num_crtcs = num_crtcs;
> -
>  	dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs,
>  				 GFP_KERNEL);
>  	if (!dev->vbl_queue)
> @@ -268,10 +271,12 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
>  	}
>  
>  	dev->vblank_disable_allowed = 0;
> +	dev->num_crtcs = num_crtcs;
> +
>  	return 0;
>  
>  err:
> -	drm_vblank_cleanup(dev);
> +	__drm_vblank_cleanup(dev);
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_vblank_init);
> -- 

Dave?

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-06-08 21:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-24 18:09 drm/nouveau: NULL pointer deref in drm_handle_vblank() on rebind Bruno Prémont
2012-05-27 20:25 ` [PATCH] drm: do not expose vblank data before drm_vblank_init completes Marcin Slusarz
2012-06-08 21:13   ` Marcin Slusarz

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.