* Re: Linux 2.6.38-rc6 [not found] ` <AANLkTinh4pF7iaUGMcv_9gPy+VBD5POsTHbF_2zPJ17r@mail.gmail.com> @ 2011-02-23 16:32 ` Linus Torvalds 2011-02-23 17:16 ` Anca Emanuel 0 siblings, 1 reply; 13+ messages in thread From: Linus Torvalds @ 2011-02-23 16:32 UTC (permalink / raw) To: Anca Emanuel, Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel Cc: Borislav Petkov, Linux Kernel Mailing List On Tue, Feb 22, 2011 at 9:42 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > General protection fault: > http://i.imgur.com/TBJ6y.jpg > > dmesg: http://pastebin.com/qD8pR8QH > config: http://pastebin.com/XEurtHWi That's drivers/video/fbmem.c: fb_release(), and the "Code:" disassembly shows that it is 1b: e8 f7 c0 29 00 callq xyz 20: 48 8b 93 b8 03 00 00 mov 0x3b8(%rbx),%rdx 27:* 48 8b 42 10 mov 0x10(%rdx),%rax <-- trapping instruction which corresponds to mutex_lock(&info->lock); if (info->fbops->fb_release) info->fbops->fb_release(info,1); so it looks like 'info->fbops' is invalid. It's in %rdx, and is 0x00d000ae00b500c2, which is definitely not a valid pointer. Looks like some bad corruption (looks like a sequence of 16-bit numbers, but it could be anything). Looks like nouveafb took over from vesafb. Did you do anything special to trigger this? Also, you do seem to have some extra patches (yama at the least). Anything else? Linus ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-23 16:32 ` Linux 2.6.38-rc6 Linus Torvalds @ 2011-02-23 17:16 ` Anca Emanuel 2011-02-24 0:28 ` Linus Torvalds 0 siblings, 1 reply; 13+ messages in thread From: Anca Emanuel @ 2011-02-23 17:16 UTC (permalink / raw) To: Linus Torvalds Cc: Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List On Wed, Feb 23, 2011 at 6:32 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Tue, Feb 22, 2011 at 9:42 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >> General protection fault: >> http://i.imgur.com/TBJ6y.jpg >> >> dmesg: http://pastebin.com/qD8pR8QH >> config: http://pastebin.com/XEurtHWi > > That's drivers/video/fbmem.c: fb_release(), and the "Code:" > disassembly shows that it is > > 1b: e8 f7 c0 29 00 callq xyz > 20: 48 8b 93 b8 03 00 00 mov 0x3b8(%rbx),%rdx > 27:* 48 8b 42 10 mov 0x10(%rdx),%rax <-- trapping instruction > > which corresponds to > > mutex_lock(&info->lock); > if (info->fbops->fb_release) > info->fbops->fb_release(info,1); > > so it looks like 'info->fbops' is invalid. It's in %rdx, and is > 0x00d000ae00b500c2, which is definitely not a valid pointer. Looks > like some bad corruption (looks like a sequence of 16-bit numbers, but > it could be anything). > > Looks like nouveafb took over from vesafb. Did you do anything special > to trigger this? No. Just boot the system. > > Also, you do seem to have some extra patches (yama at the least). Anything else? I used git clone, nothing else. First time 2.6.38-rc6 was working. After an update from ubuntu I get that error at boot. The dmesg is from Ubuntu 11.04 with their kernel and is working fine. > > Linus > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-23 17:16 ` Anca Emanuel @ 2011-02-24 0:28 ` Linus Torvalds 2011-02-24 0:43 ` Dave Airlie 2011-02-24 13:20 ` Anca Emanuel 0 siblings, 2 replies; 13+ messages in thread From: Linus Torvalds @ 2011-02-24 0:28 UTC (permalink / raw) To: Anca Emanuel Cc: Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List On Wed, Feb 23, 2011 at 9:16 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >> >> Looks like nouveafb took over from vesafb. Did you do anything special >> to trigger this? > > No. Just boot the system. Every boot? And just out of interest, what happens if you don't have the vesafb driver at all? Linus ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-24 0:28 ` Linus Torvalds @ 2011-02-24 0:43 ` Dave Airlie 2011-02-24 13:20 ` Anca Emanuel 1 sibling, 0 replies; 13+ messages in thread From: Dave Airlie @ 2011-02-24 0:43 UTC (permalink / raw) To: Linus Torvalds Cc: Anca Emanuel, Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List On Thu, Feb 24, 2011 at 10:28 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Wed, Feb 23, 2011 at 9:16 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >>> >>> Looks like nouveafb took over from vesafb. Did you do anything special >>> to trigger this? >> >> No. Just boot the system. > > Every boot? > > And just out of interest, what happens if you don't have the vesafb > driver at all? > I think this is a race condition somewhere with plymouth getting access to vesafb before it gets kicked off the hw, I'm assuming removing the vga= line from the command line will stop it, Dave. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-24 0:28 ` Linus Torvalds 2011-02-24 0:43 ` Dave Airlie @ 2011-02-24 13:20 ` Anca Emanuel 2011-02-24 16:37 ` Linus Torvalds 1 sibling, 1 reply; 13+ messages in thread From: Anca Emanuel @ 2011-02-24 13:20 UTC (permalink / raw) To: Linus Torvalds Cc: Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List On Thu, Feb 24, 2011 at 2:28 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Wed, Feb 23, 2011 at 9:16 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >>> >>> Looks like nouveafb took over from vesafb. Did you do anything special >>> to trigger this? >> >> No. Just boot the system. > > Every boot? Yes. > > And just out of interest, what happens if you don't have the vesafb > driver at all? > > Linus > I used 'e' option from grub, removed the 'set gfxpayload = $linux_gfx_mode' and it works. dmesg: http://pastebin.com/JAZsk4vD ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-24 13:20 ` Anca Emanuel @ 2011-02-24 16:37 ` Linus Torvalds 2011-02-25 0:48 ` Anca Emanuel 0 siblings, 1 reply; 13+ messages in thread From: Linus Torvalds @ 2011-02-24 16:37 UTC (permalink / raw) To: Anca Emanuel Cc: Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 737 bytes --] On Thu, Feb 24, 2011 at 5:20 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >> >> Every boot? > > Yes. > >> And just out of interest, what happens if you don't have the vesafb >> driver at all? > > I used 'e' option from grub, removed the 'set gfxpayload = $linux_gfx_mode' > and it works. > > dmesg: http://pastebin.com/JAZsk4vD Hmm. So it definitely seems to be the hand-over. Does this patch make any difference? When we unregister the old framebuffer, we still leave it in the registered_fb[] array, which looks wrong. But it would also be interesting to hear if setting CONFIG_SLUB_DEBUG_ON or CONFIG_DEBUG_PAGEALLOC makes any difference (they'd help detect accesses to free'd data structures). Linus [-- Attachment #2: patch.diff --] [-- Type: text/x-patch, Size: 497 bytes --] drivers/video/fbmem.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e2bf953..e8f8925 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct apertures_struct *a, "%s vs %s - removing generic driver\n", name, registered_fb[i]->fix.id); unregister_framebuffer(registered_fb[i]); + registered_fb[i] = NULL; } } } ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-24 16:37 ` Linus Torvalds @ 2011-02-25 0:48 ` Anca Emanuel 2011-02-25 0:54 ` Linus Torvalds 0 siblings, 1 reply; 13+ messages in thread From: Anca Emanuel @ 2011-02-25 0:48 UTC (permalink / raw) To: Linus Torvalds Cc: linux-fbdev, Herton Ronaldo Krzesinski, Linux Kernel Mailing List, dri-devel, Ben Skeggs, Borislav Petkov, Dave Airlie On Thu, Feb 24, 2011 at 6:37 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Thu, Feb 24, 2011 at 5:20 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >>> >>> Every boot? >> >> Yes. >> >>> And just out of interest, what happens if you don't have the vesafb >>> driver at all? >> >> I used 'e' option from grub, removed the 'set gfxpayload = $linux_gfx_mode' >> and it works. >> >> dmesg: http://pastebin.com/JAZsk4vD > > Hmm. So it definitely seems to be the hand-over. > > Does this patch make any difference? When we unregister the old > framebuffer, we still leave it in the registered_fb[] array, which > looks wrong. But it would also be interesting to hear if setting > CONFIG_SLUB_DEBUG_ON or CONFIG_DEBUG_PAGEALLOC makes any difference > (they'd help detect accesses to free'd data structures). > > Linus > drivers/video/fbmem.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e2bf953..e8f8925 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct apertures_struct *a, "%s vs %s - removing generic driver\n", name, registered_fb[i]->fix.id); unregister_framebuffer(registered_fb[i]); + registered_fb[i] = NULL; } } } Tested the patch, and now I get this: dmesg: http://pastebin.com/ieMNrA7C [ 12.252328] BUG: unable to handle kernel NULL pointer dereference at 00000000000003b8 [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 [ 12.252354] PGD 78e6c067 PUD 78e6d067 PMD 0 [ 12.252360] Oops: 0000 [#1] SMP [ 12.252364] last sysfs file: /sys/module/snd/initstate [ 12.252370] CPU 0 [ 12.252372] Modules linked in: nouveau(+) snd ttm drm_kms_helper psmouse serio_raw drm soundcore lp snd_page_alloc i2c_algo_bit video parport pata_marvell ahci r8169 libahci [ 12.252393] [ 12.252397] Pid: 244, comm: plymouthd Not tainted 2.6.38-rc6-git3-patch-linus+ #2 MICRO-STAR INTERNATIONAL CO.,LTD MS-7360/MS-7360 [ 12.252407] RIP: 0010:[<ffffffff81311178>] [<ffffffff81311178>] fb_mmap+0x58/0x1d0 [ 12.252414] RSP: 0018:ffff880078e8fd88 EFLAGS: 00010293 [ 12.252418] RAX: 00000000ffffffea RBX: ffff88007047d228 RCX: 0000000000000000 [ 12.252423] RDX: 000fffffffffffff RSI: ffff88007047d228 RDI: ffff880078f5d840 [ 12.252428] RBP: ffff880078e8fdc8 R08: 0000000000000000 R09: ffff88007047d228 [ 12.252432] R10: ffff88006f9d9cf0 R11: ffff88006f9d9d28 R12: ffff880037363800 [ 12.252437] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88007047d228 [ 12.252442] FS: 00007fb5fbaa4720(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 [ 12.252448] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 12.252453] CR2: 00000000000003b8 CR3: 0000000078e6b000 CR4: 00000000000006f0 [ 12.252458] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 12.252463] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 12.252468] Process plymouthd (pid: 244, threadinfo ffff880078e8e000, task ffff88003737ad80) [ 12.252473] Stack: [ 12.252476] ffff880037363800 00000000000000b8 ffff880078e8fdd8 ffffffffffffffea [ 12.252484] ffff880037363800 00000000000006bb 00000000006bb000 ffff88007047d228 [ 12.252491] ffff880078e8fe98 ffffffff81130543 ffff880078f5d840 0000000000000000 [ 12.252499] Call Trace: [ 12.252507] [<ffffffff81130543>] mmap_region+0x3c3/0x500 [ 12.252514] [<ffffffff81010d7e>] ? arch_get_unmapped_area_topdown+0x1ce/0x2f0 [ 12.252521] [<ffffffff811309c4>] do_mmap_pgoff+0x344/0x380 [ 12.252528] [<ffffffff810524f1>] ? finish_task_switch+0x41/0xe0 [ 12.252535] [<ffffffff815ac0c3>] ? schedule+0x403/0xa00 [ 12.252541] [<ffffffff81130bfe>] sys_mmap_pgoff+0x1fe/0x230 [ 12.252546] [<ffffffff810108c9>] sys_mmap+0x29/0x30 [ 12.252551] [<ffffffff8100bf02>] system_call_fastpath+0x16/0x1b [ 12.252556] Code: ba ff ff ff ff ff ff 0f 00 48 89 f3 48 8b 40 30 8b 80 b8 00 00 00 25 ff ff 0f 00 49 39 d6 4c 8b 2c c5 c0 cf aa 81 b8 ea ff ff ff <4d> 8b bd b8 03 00 00 76 1f 48 8b 5d d8 4c 8b 65 e0 4c 8b 6d e8 [ 12.252603] RIP [<ffffffff81311178>] fb_mmap+0x58/0x1d0 [ 12.252608] RSP <ffff880078e8fd88> [ 12.252611] CR2: 00000000000003b8 [ 12.252616] ---[ end trace 381165bafe65d748 ]--- ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 0:48 ` Anca Emanuel @ 2011-02-25 0:54 ` Linus Torvalds 2011-02-25 1:14 ` Dave Airlie 0 siblings, 1 reply; 13+ messages in thread From: Linus Torvalds @ 2011-02-25 0:54 UTC (permalink / raw) To: Anca Emanuel Cc: Dave Airlie, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Herton Ronaldo Krzesinski, Linux Kernel Mailing List On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c > index e2bf953..e8f8925 100644 > --- a/drivers/video/fbmem.c > +++ b/drivers/video/fbmem.c > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct > apertures_struct *a, > "%s vs %s - removing generic driver\n", > name, registered_fb[i]->fix.id); > unregister_framebuffer(registered_fb[i]); > + registered_fb[i] = NULL; > > Tested the patch, and now I get this: > dmesg: http://pastebin.com/ieMNrA7C > > [ 12.252328] BUG: unable to handle kernel NULL pointer dereference > at 00000000000003b8 > [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 Ok, goodie. Or not so goodie, but it does make it clear that yeah, the fb code seems to be using stale pointers from that registered_fb[] array, and the whole unregistration process is just racing with people using it. Herton had that much bigger patch, can you test it? Linus ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 0:54 ` Linus Torvalds @ 2011-02-25 1:14 ` Dave Airlie 2011-02-25 1:47 ` Anca Emanuel 0 siblings, 1 reply; 13+ messages in thread From: Dave Airlie @ 2011-02-25 1:14 UTC (permalink / raw) To: Linus Torvalds Cc: Anca Emanuel, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Herton Ronaldo Krzesinski, Linux Kernel Mailing List On Thu, 2011-02-24 at 16:54 -0800, Linus Torvalds wrote: > On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > > > > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c > > index e2bf953..e8f8925 100644 > > --- a/drivers/video/fbmem.c > > +++ b/drivers/video/fbmem.c > > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct > > apertures_struct *a, > > "%s vs %s - removing generic driver\n", > > name, registered_fb[i]->fix.id); > > unregister_framebuffer(registered_fb[i]); > > + registered_fb[i] = NULL; > > > > Tested the patch, and now I get this: > > dmesg: http://pastebin.com/ieMNrA7C > > > > [ 12.252328] BUG: unable to handle kernel NULL pointer dereference > > at 00000000000003b8 > > [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 > > Ok, goodie. > > Or not so goodie, but it does make it clear that yeah, the fb code > seems to be using stale pointers from that registered_fb[] array, and > the whole unregistration process is just racing with people using it. > > Herton had that much bigger patch, can you test it? I think Andy's patch worked, not sure why it fell between the cracks, either didn't appear on lkml or in my inbox at all. if we can get Herton to repost it properly + a tested by I'm happy for it to go in. Dave. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 1:14 ` Dave Airlie @ 2011-02-25 1:47 ` Anca Emanuel 2011-02-25 1:56 ` Anca Emanuel 0 siblings, 1 reply; 13+ messages in thread From: Anca Emanuel @ 2011-02-25 1:47 UTC (permalink / raw) To: Dave Airlie Cc: Linus Torvalds, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Herton Ronaldo Krzesinski, Linux Kernel Mailing List On Fri, Feb 25, 2011 at 3:14 AM, Dave Airlie <airlied@redhat.com> wrote: > On Thu, 2011-02-24 at 16:54 -0800, Linus Torvalds wrote: >> On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >> > >> > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c >> > index e2bf953..e8f8925 100644 >> > --- a/drivers/video/fbmem.c >> > +++ b/drivers/video/fbmem.c >> > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct >> > apertures_struct *a, >> > "%s vs %s - removing generic driver\n", >> > name, registered_fb[i]->fix.id); >> > unregister_framebuffer(registered_fb[i]); >> > + registered_fb[i] = NULL; >> > >> > Tested the patch, and now I get this: >> > dmesg: http://pastebin.com/ieMNrA7C >> > >> > [ 12.252328] BUG: unable to handle kernel NULL pointer dereference >> > at 00000000000003b8 >> > [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 >> >> Ok, goodie. >> >> Or not so goodie, but it does make it clear that yeah, the fb code >> seems to be using stale pointers from that registered_fb[] array, and >> the whole unregistration process is just racing with people using it. >> >> Herton had that much bigger patch, can you test it? > > I think Andy's patch worked, not sure why it fell between the cracks, > either didn't appear on lkml or in my inbox at all. > > if we can get Herton to repost it properly + a tested by I'm happy for > it to go in. > > Dave. > > Tested Andy's patch and it works ! http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-natty.git;a=commit;hÅa742b5f78e161d6a13853a7e3e6e1dfa429e69 Tested-by: Anca Emanuel <anca.emanuel@gmail.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 1:47 ` Anca Emanuel @ 2011-02-25 1:56 ` Anca Emanuel 2011-02-25 14:49 ` Herton Ronaldo Krzesinski 0 siblings, 1 reply; 13+ messages in thread From: Anca Emanuel @ 2011-02-25 1:56 UTC (permalink / raw) To: Dave Airlie Cc: Linus Torvalds, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Herton Ronaldo Krzesinski, Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 1936 bytes --] On Fri, Feb 25, 2011 at 3:47 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > On Fri, Feb 25, 2011 at 3:14 AM, Dave Airlie <airlied@redhat.com> wrote: >> On Thu, 2011-02-24 at 16:54 -0800, Linus Torvalds wrote: >>> On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: >>> > >>> > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c >>> > index e2bf953..e8f8925 100644 >>> > --- a/drivers/video/fbmem.c >>> > +++ b/drivers/video/fbmem.c >>> > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct >>> > apertures_struct *a, >>> > "%s vs %s - removing generic driver\n", >>> > name, registered_fb[i]->fix.id); >>> > unregister_framebuffer(registered_fb[i]); >>> > + registered_fb[i] = NULL; >>> > >>> > Tested the patch, and now I get this: >>> > dmesg: http://pastebin.com/ieMNrA7C >>> > >>> > [ 12.252328] BUG: unable to handle kernel NULL pointer dereference >>> > at 00000000000003b8 >>> > [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 >>> >>> Ok, goodie. >>> >>> Or not so goodie, but it does make it clear that yeah, the fb code >>> seems to be using stale pointers from that registered_fb[] array, and >>> the whole unregistration process is just racing with people using it. >>> >>> Herton had that much bigger patch, can you test it? >> >> I think Andy's patch worked, not sure why it fell between the cracks, >> either didn't appear on lkml or in my inbox at all. >> >> if we can get Herton to repost it properly + a tested by I'm happy for >> it to go in. >> >> Dave. >> >> > > Tested Andy's patch and it works ! > http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-natty.git;a=commit;h=c5a742b5f78e161d6a13853a7e3e6e1dfa429e69 > > Tested-by: Anca Emanuel <anca.emanuel@gmail.com> > link to patch: http://is.gd/otIfGc [-- Attachment #2: patch --] [-- Type: application/octet-stream, Size: 9935 bytes --] From c5a742b5f78e161d6a13853a7e3e6e1dfa429e69 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft <apw@canonical.com> Date: Thu, 29 Jul 2010 16:48:20 +0100 Subject: [PATCH 1/1] UBUNTU: SAUCE: fbcon -- fix race between open and removal of framebuffers Currently there is no locking for updates to the registered_fb list. This allows an open through /dev/fbN to pick up a registered framebuffer pointer in parallel with it being released, as happens when a conflicting framebuffer is ejected or on module unload. There is also no reference counting on the framebuffer descriptor which is referenced from all open files, leading to references to released or reused memory to persist on these open files. This patch adds a reference count to the framebuffer descriptor to prevent it from being released until after all pending opens are closed. This allows the pending opens to detect the closed status and unmap themselves. It also adds locking to the framebuffer lookup path, locking it against the removal path such that it is possible to atomically lookup and take a reference to the descriptor. It also adds locking to the read and write paths which currently could access the framebuffer descriptor after it has been freed. Finally it moves the device to FBINFO_STATE_REMOVED to indicate that all access should be errored for this device. Signed-off-by: Andy Whitcroft <apw@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com> --- drivers/video/fbmem.c | 132 ++++++++++++++++++++++++++++++++++++++----------- include/linux/fb.h | 2 + 2 files changed, 105 insertions(+), 29 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e2bf953..877200b 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -42,6 +42,8 @@ #define FBPIXMAPSIZE (1024 * 8) +/* Protects the registered framebuffer list and count. */ +static DEFINE_SPINLOCK(registered_lock); struct fb_info *registered_fb[FB_MAX] __read_mostly; int num_registered_fb __read_mostly; @@ -694,9 +696,7 @@ static ssize_t fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file->private_data; u8 *buffer, *dst; u8 __iomem *src; int c, cnt = 0, err = 0; @@ -705,19 +705,28 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (!info || ! info->screen_base) return -ENODEV; - if (info->state != FBINFO_STATE_RUNNING) - return -EPERM; + if (!lock_fb_info(info)) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) { + err = -EPERM; + goto out_fb_info; + } - if (info->fbops->fb_read) - return info->fbops->fb_read(info, buf, count, ppos); + if (info->fbops->fb_read) { + err = info->fbops->fb_read(info, buf, count, ppos); + goto out_fb_info; + } total_size = info->screen_size; if (total_size == 0) total_size = info->fix.smem_len; - if (p >= total_size) - return 0; + if (p >= total_size) { + err = 0; + goto out_fb_info; + } if (count >= total_size) count = total_size; @@ -727,8 +736,10 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + if (!buffer) { + err = -ENOMEM; + goto out_fb_info; + } src = (u8 __iomem *) (info->screen_base + p); @@ -751,19 +762,21 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) cnt += c; count -= c; } + if (!err) + err = cnt; kfree(buffer); +out_fb_info: + unlock_fb_info(info); - return (err) ? err : cnt; + return err; } static ssize_t fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file->private_data; u8 *buffer, *src; u8 __iomem *dst; int c, cnt = 0, err = 0; @@ -772,8 +785,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) if (!info || !info->screen_base) return -ENODEV; - if (info->state != FBINFO_STATE_RUNNING) - return -EPERM; + if (!lock_fb_info(info)) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) { + err = -EPERM; + goto out_fb_info; + } if (info->fbops->fb_write) return info->fbops->fb_write(info, buf, count, ppos); @@ -783,8 +801,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) if (total_size == 0) total_size = info->fix.smem_len; - if (p > total_size) - return -EFBIG; + if (p > total_size) { + err = -EFBIG; + goto out_fb_info; + } if (count > total_size) { err = -EFBIG; @@ -800,8 +820,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + if (!buffer) { + err = -ENOMEM; + goto out_fb_info; + } dst = (u8 __iomem *) (info->screen_base + p); @@ -825,10 +847,14 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) cnt += c; count -= c; } + if (cnt) + err = cnt; kfree(buffer); +out_fb_info: + unlock_fb_info(info); - return (cnt) ? cnt : err; + return err; } int @@ -1303,8 +1329,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, static int fb_mmap(struct file *file, struct vm_area_struct * vma) { - int fbidx = iminor(file->f_path.dentry->d_inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info * const info = file->private_data; struct fb_ops *fb = info->fbops; unsigned long off; unsigned long start; @@ -1316,6 +1341,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) if (!fb) return -ENODEV; mutex_lock(&info->mm_lock); + if (info->state == FBINFO_STATE_REMOVED) { + mutex_unlock(&info->mm_lock); + return -ENODEV; + } + if (fb->fb_mmap) { int res; res = fb->fb_mmap(info, vma); @@ -1352,6 +1382,34 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) return 0; } +static struct fb_info *get_framebuffer_info(int idx) +__acquires(®istered_lock) +__releases(®istered_lock) +{ + struct fb_info *fb_info; + + spin_lock(®istered_lock); + fb_info = registered_fb[idx]; + fb_info->ref_count++; + spin_unlock(®istered_lock); + + return fb_info; +} + +static void put_framebuffer_info(struct fb_info *fb_info) +__acquires(®istered_lock) +__releases(®istered_lock) +{ + int keep; + + spin_lock(®istered_lock); + keep = --fb_info->ref_count; + spin_unlock(®istered_lock); + + if (!keep && fb_info->fbops->fb_destroy) + fb_info->fbops->fb_destroy(fb_info); +} + static int fb_open(struct inode *inode, struct file *file) __acquires(&info->lock) @@ -1363,13 +1421,17 @@ __releases(&info->lock) if (fbidx >= FB_MAX) return -ENODEV; - info = registered_fb[fbidx]; + info = get_framebuffer_info(fbidx); if (!info) request_module("fb%d", fbidx); - info = registered_fb[fbidx]; + info = get_framebuffer_info(fbidx); if (!info) return -ENODEV; mutex_lock(&info->lock); + if (info->state == FBINFO_STATE_REMOVED) { + res = -ENODEV; + goto out; + } if (!try_module_get(info->fbops->owner)) { res = -ENODEV; goto out; @@ -1386,6 +1448,8 @@ __releases(&info->lock) #endif out: mutex_unlock(&info->lock); + if (res) + put_framebuffer_info(info); return res; } @@ -1401,6 +1465,7 @@ __releases(&info->lock) info->fbops->fb_release(info,1); module_put(info->fbops->owner); mutex_unlock(&info->lock); + put_framebuffer_info(info); return 0; } @@ -1549,6 +1614,7 @@ register_framebuffer(struct fb_info *fb_info) fb_info->node = i; mutex_init(&fb_info->lock); mutex_init(&fb_info->mm_lock); + fb_info->ref_count = 1; fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), NULL, "fb%d", i); @@ -1592,7 +1658,6 @@ register_framebuffer(struct fb_info *fb_info) return 0; } - /** * unregister_framebuffer - releases a frame buffer device * @fb_info: frame buffer info structure @@ -1627,6 +1692,16 @@ unregister_framebuffer(struct fb_info *fb_info) return -ENODEV; event.info = fb_info; ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); + if (!ret) { + mutex_lock(&fb_info->mm_lock); + /* + * We must prevent any operations for this transition, we + * already have info->lock so grab the info->mm_lock to hold + * the remainder. + */ + fb_info->state = FBINFO_STATE_REMOVED; + mutex_unlock(&fb_info->mm_lock); + } unlock_fb_info(fb_info); if (ret) { @@ -1646,8 +1721,7 @@ unregister_framebuffer(struct fb_info *fb_info) fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); /* this may free fb info */ - if (fb_info->fbops->fb_destroy) - fb_info->fbops->fb_destroy(fb_info); + put_framebuffer_info(fb_info); done: return ret; } diff --git a/include/linux/fb.h b/include/linux/fb.h index 68ba85a..1e8b785 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -832,6 +832,7 @@ struct fb_tile_ops { struct fb_info { int node; int flags; + int ref_count; struct mutex lock; /* Lock for open/release/ioctl funcs */ struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */ struct fb_var_screeninfo var; /* Current var */ @@ -871,6 +872,7 @@ struct fb_info { void *pseudo_palette; /* Fake palette of 16 colors */ #define FBINFO_STATE_RUNNING 0 #define FBINFO_STATE_SUSPENDED 1 +#define FBINFO_STATE_REMOVED 2 u32 state; /* Hardware state i.e suspend */ void *fbcon_par; /* fbcon use-only private area */ /* From here on everything is device dependent */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 1:56 ` Anca Emanuel @ 2011-02-25 14:49 ` Herton Ronaldo Krzesinski 2011-03-22 8:36 ` Paul Mundt 0 siblings, 1 reply; 13+ messages in thread From: Herton Ronaldo Krzesinski @ 2011-02-25 14:49 UTC (permalink / raw) To: Anca Emanuel Cc: Dave Airlie, Linus Torvalds, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List, Andy Whitcroft On Fri, Feb 25, 2011 at 03:56:20AM +0200, Anca Emanuel wrote: > On Fri, Feb 25, 2011 at 3:47 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > > On Fri, Feb 25, 2011 at 3:14 AM, Dave Airlie <airlied@redhat.com> wrote: > >> On Thu, 2011-02-24 at 16:54 -0800, Linus Torvalds wrote: > >>> On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > >>> > > >>> > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c > >>> > index e2bf953..e8f8925 100644 > >>> > --- a/drivers/video/fbmem.c > >>> > +++ b/drivers/video/fbmem.c > >>> > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct > >>> > apertures_struct *a, > >>> > "%s vs %s - removing generic driver\n", > >>> > name, registered_fb[i]->fix.id); > >>> > unregister_framebuffer(registered_fb[i]); > >>> > + registered_fb[i] = NULL; > >>> > > >>> > Tested the patch, and now I get this: > >>> > dmesg: http://pastebin.com/ieMNrA7C > >>> > > >>> > [ 12.252328] BUG: unable to handle kernel NULL pointer dereference > >>> > at 00000000000003b8 > >>> > [ 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 > >>> > >>> Ok, goodie. > >>> > >>> Or not so goodie, but it does make it clear that yeah, the fb code > >>> seems to be using stale pointers from that registered_fb[] array, and > >>> the whole unregistration process is just racing with people using it. > >>> > >>> Herton had that much bigger patch, can you test it? > >> > >> I think Andy's patch worked, not sure why it fell between the cracks, > >> either didn't appear on lkml or in my inbox at all. > >> > >> if we can get Herton to repost it properly + a tested by I'm happy for > >> it to go in. > >> > >> Dave. > >> > >> > > > > Tested Andy's patch and it works ! > > http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-natty.git;a=commit;hÅa742b5f78e161d6a13853a7e3e6e1dfa429e69 > > > > Tested-by: Anca Emanuel <anca.emanuel@gmail.com> > > > > link to patch: http://is.gd/otIfGc Adding Andy on CC (btw he is away for today, may get some time to answer). Andy, can you repost the patch? -- []'s Herton ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Linux 2.6.38-rc6 2011-02-25 14:49 ` Herton Ronaldo Krzesinski @ 2011-03-22 8:36 ` Paul Mundt 0 siblings, 0 replies; 13+ messages in thread From: Paul Mundt @ 2011-03-22 8:36 UTC (permalink / raw) To: Herton Ronaldo Krzesinski Cc: Anca Emanuel, Dave Airlie, Linus Torvalds, linux-fbdev, Ben Skeggs, dri-devel, Borislav Petkov, Linux Kernel Mailing List, Andy Whitcroft On Fri, Feb 25, 2011 at 11:49:21AM -0300, Herton Ronaldo Krzesinski wrote: > On Fri, Feb 25, 2011 at 03:56:20AM +0200, Anca Emanuel wrote: > > On Fri, Feb 25, 2011 at 3:47 AM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > > > On Fri, Feb 25, 2011 at 3:14 AM, Dave Airlie <airlied@redhat.com> wrote: > > >> On Thu, 2011-02-24 at 16:54 -0800, Linus Torvalds wrote: > > >>> On Thu, Feb 24, 2011 at 4:48 PM, Anca Emanuel <anca.emanuel@gmail.com> wrote: > > >>> > > > >>> > diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c > > >>> > index e2bf953..e8f8925 100644 > > >>> > --- a/drivers/video/fbmem.c > > >>> > +++ b/drivers/video/fbmem.c > > >>> > @@ -1511,6 +1511,7 @@ void remove_conflicting_framebuffers(struct > > >>> > apertures_struct *a, > > >>> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s vs %s - removing generic driver\n", > > >>> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name, registered_fb[i]->fix.id); > > >>> > ? ? ? ? ? ? ? ? ? ? ? ?unregister_framebuffer(registered_fb[i]); > > >>> > + ? ? ? ? ? ? ? ? ? ? ? registered_fb[i] = NULL; > > >>> > > > >>> > Tested the patch, and now I get this: > > >>> > dmesg: http://pastebin.com/ieMNrA7C > > >>> > > > >>> > [ ? 12.252328] BUG: unable to handle kernel NULL pointer dereference > > >>> > at 00000000000003b8 > > >>> > [ ? 12.252342] IP: [<ffffffff81311178>] fb_mmap+0x58/0x1d0 > > >>> > > >>> Ok, goodie. > > >>> > > >>> Or not so goodie, but it does make it clear that yeah, the fb code > > >>> seems to be using stale pointers from that registered_fb[] array, and > > >>> the whole unregistration process is just racing with people using it. > > >>> > > >>> Herton had that much bigger patch, can you test it? > > >> > > >> I think Andy's patch worked, not sure why it fell between the cracks, > > >> either didn't appear on lkml or in my inbox at all. > > >> > > >> if we can get Herton to repost it properly + a tested by I'm happy for > > >> it to go in. > > >> > > >> Dave. > > >> > > >> > > > > > > Tested Andy's patch and it works ! > > > http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-natty.git;a=commit;hÅa742b5f78e161d6a13853a7e3e6e1dfa429e69 > > > > > > Tested-by: Anca Emanuel <anca.emanuel@gmail.com> > > > > > > > link to patch: http://is.gd/otIfGc > > Adding Andy on CC (btw he is away for today, may get some time to answer). > > Andy, can you repost the patch? > This is the first I've seen the patch as well, but fortunately patchwork caught it on the Cc. There's also an outstanding patch for fixing an AB-BA deadlock between the fb_info lock and the console lock which this will clash with. I'm happy to rework that patch on top of Andy's patch for Anca and/or Herton to test, though. I'll need to do some more testing locally as well.. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-03-22 8:36 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <AANLkTi=TTZ57d1wUz1uH3R6igN8O77iDvSLMW=t86g9V@mail.gmail.com> [not found] ` <20110222140349.GA20708@kryptos.osrc.amd.com> [not found] ` <AANLkTikESHHfjBqoLFOno6qQz-NXEAo-wBY5JEeAW61N@mail.gmail.com> [not found] ` <AANLkTinh4pF7iaUGMcv_9gPy+VBD5POsTHbF_2zPJ17r@mail.gmail.com> 2011-02-23 16:32 ` Linux 2.6.38-rc6 Linus Torvalds 2011-02-23 17:16 ` Anca Emanuel 2011-02-24 0:28 ` Linus Torvalds 2011-02-24 0:43 ` Dave Airlie 2011-02-24 13:20 ` Anca Emanuel 2011-02-24 16:37 ` Linus Torvalds 2011-02-25 0:48 ` Anca Emanuel 2011-02-25 0:54 ` Linus Torvalds 2011-02-25 1:14 ` Dave Airlie 2011-02-25 1:47 ` Anca Emanuel 2011-02-25 1:56 ` Anca Emanuel 2011-02-25 14:49 ` Herton Ronaldo Krzesinski 2011-03-22 8:36 ` Paul Mundt
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).