From: Greg Kroah-Hartman Date: Thu, 22 Mar 2012 20:25:31 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.26~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5d5bcb51c0c3f85f47e5eb14457b622a52aeed0;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch cdc-wdm-fix-more-races-on-the-read-path.patch futex-cover-all-pi-opcodes-with-cmpxchg-enabled-check.patch sysfs-fix-memory-leak-in-sysfs_sd_setsecdata.patch tty-moxa-fix-bit-test-in-moxa_start.patch tty-wrong-unicode-value-copied-in-con_set_unimap.patch usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch usb-serial-fix-console-error-reporting.patch --- diff --git a/queue-3.0/cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch b/queue-3.0/cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch new file mode 100644 index 00000000000..ca02fe0b018 --- /dev/null +++ b/queue-3.0/cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch @@ -0,0 +1,33 @@ +From b7a205545345578712611106b371538992e142ff Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 12 Feb 2012 06:02:43 +0000 +Subject: cdc-wdm: Don't clear WDM_READ unless entire read buffer is emptied +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ben Hutchings + +commit b7a205545345578712611106b371538992e142ff upstream. + +The WDM_READ flag is cleared later iff desc->length is reduced to 0. + +Signed-off-by: Ben Hutchings +Tested-by: Bjørn Mork +Cc: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -457,7 +457,6 @@ retry: + spin_unlock_irq(&desc->iuspin); + goto retry; + } +- clear_bit(WDM_READ, &desc->flags); + cntr = desc->length; + spin_unlock_irq(&desc->iuspin); + } diff --git a/queue-3.0/cdc-wdm-fix-more-races-on-the-read-path.patch b/queue-3.0/cdc-wdm-fix-more-races-on-the-read-path.patch new file mode 100644 index 00000000000..ececdfed660 --- /dev/null +++ b/queue-3.0/cdc-wdm-fix-more-races-on-the-read-path.patch @@ -0,0 +1,85 @@ +From 711c68b3c0f7a924ffbee4aa962d8f62b85188ff Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 12 Feb 2012 06:00:41 +0000 +Subject: cdc-wdm: Fix more races on the read path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ben Hutchings + +commit 711c68b3c0f7a924ffbee4aa962d8f62b85188ff upstream. + +We must not allow the input buffer length to change while we're +shuffling the buffer contents. We also mustn't clear the WDM_READ +flag after more data might have arrived. Therefore move both of these +into the spinlocked region at the bottom of wdm_read(). + +When reading desc->length without holding the iuspin lock, use +ACCESS_ONCE() to ensure the compiler doesn't re-read it with +inconsistent results. + +Signed-off-by: Ben Hutchings +Tested-by: Bjørn Mork +Cc: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -397,7 +397,7 @@ outnl: + static ssize_t wdm_read + (struct file *file, char __user *buffer, size_t count, loff_t *ppos) + { +- int rv, cntr = 0; ++ int rv, cntr; + int i = 0; + struct wdm_device *desc = file->private_data; + +@@ -406,7 +406,8 @@ static ssize_t wdm_read + if (rv < 0) + return -ERESTARTSYS; + +- if (desc->length == 0) { ++ cntr = ACCESS_ONCE(desc->length); ++ if (cntr == 0) { + desc->read = 0; + retry: + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { +@@ -457,25 +458,30 @@ retry: + goto retry; + } + clear_bit(WDM_READ, &desc->flags); ++ cntr = desc->length; + spin_unlock_irq(&desc->iuspin); + } + +- cntr = count > desc->length ? desc->length : count; ++ if (cntr > count) ++ cntr = count; + rv = copy_to_user(buffer, desc->ubuf, cntr); + if (rv > 0) { + rv = -EFAULT; + goto err; + } + ++ spin_lock_irq(&desc->iuspin); ++ + for (i = 0; i < desc->length - cntr; i++) + desc->ubuf[i] = desc->ubuf[i + cntr]; + +- spin_lock_irq(&desc->iuspin); + desc->length -= cntr; +- spin_unlock_irq(&desc->iuspin); + /* in case we had outstanding data */ + if (!desc->length) + clear_bit(WDM_READ, &desc->flags); ++ ++ spin_unlock_irq(&desc->iuspin); ++ + rv = cntr; + + err: diff --git a/queue-3.0/futex-cover-all-pi-opcodes-with-cmpxchg-enabled-check.patch b/queue-3.0/futex-cover-all-pi-opcodes-with-cmpxchg-enabled-check.patch new file mode 100644 index 00000000000..e6a41d11732 --- /dev/null +++ b/queue-3.0/futex-cover-all-pi-opcodes-with-cmpxchg-enabled-check.patch @@ -0,0 +1,61 @@ +From 59263b513c11398cd66a52d4c5b2b118ce1e0359 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 15 Feb 2012 12:08:34 +0100 +Subject: futex: Cover all PI opcodes with cmpxchg enabled check + +From: Thomas Gleixner + +commit 59263b513c11398cd66a52d4c5b2b118ce1e0359 upstream. + +Some of the newer futex PI opcodes do not check the cmpxchg enabled +variable and call unconditionally into the handling functions. Cover +all PI opcodes in a separate check. + +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Cc: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2641,6 +2641,16 @@ long do_futex(u32 __user *uaddr, int op, + } + + switch (cmd) { ++ case FUTEX_LOCK_PI: ++ case FUTEX_UNLOCK_PI: ++ case FUTEX_TRYLOCK_PI: ++ case FUTEX_WAIT_REQUEUE_PI: ++ case FUTEX_CMP_REQUEUE_PI: ++ if (!futex_cmpxchg_enabled) ++ return -ENOSYS; ++ } ++ ++ switch (cmd) { + case FUTEX_WAIT: + val3 = FUTEX_BITSET_MATCH_ANY; + case FUTEX_WAIT_BITSET: +@@ -2661,16 +2671,13 @@ long do_futex(u32 __user *uaddr, int op, + ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3); + break; + case FUTEX_LOCK_PI: +- if (futex_cmpxchg_enabled) +- ret = futex_lock_pi(uaddr, flags, val, timeout, 0); ++ ret = futex_lock_pi(uaddr, flags, val, timeout, 0); + break; + case FUTEX_UNLOCK_PI: +- if (futex_cmpxchg_enabled) +- ret = futex_unlock_pi(uaddr, flags); ++ ret = futex_unlock_pi(uaddr, flags); + break; + case FUTEX_TRYLOCK_PI: +- if (futex_cmpxchg_enabled) +- ret = futex_lock_pi(uaddr, flags, 0, timeout, 1); ++ ret = futex_lock_pi(uaddr, flags, 0, timeout, 1); + break; + case FUTEX_WAIT_REQUEUE_PI: + val3 = FUTEX_BITSET_MATCH_ANY; diff --git a/queue-3.0/series b/queue-3.0/series index 29bfa5f863d..deb0351c178 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -12,3 +12,12 @@ powerpc-usb-fix-bug-of-kernel-hang-when-initializing-usb.patch usb-musb-reselect-index-reg-in-interrupt-context.patch usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch usb-gadget-make-g_hid-device-class-conform-to-spec.patch +futex-cover-all-pi-opcodes-with-cmpxchg-enabled-check.patch +sysfs-fix-memory-leak-in-sysfs_sd_setsecdata.patch +tty-moxa-fix-bit-test-in-moxa_start.patch +tty-wrong-unicode-value-copied-in-con_set_unimap.patch +usb-serial-fix-console-error-reporting.patch +cdc-wdm-fix-more-races-on-the-read-path.patch +cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch +usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch +usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch diff --git a/queue-3.0/sysfs-fix-memory-leak-in-sysfs_sd_setsecdata.patch b/queue-3.0/sysfs-fix-memory-leak-in-sysfs_sd_setsecdata.patch new file mode 100644 index 00000000000..bdb00812c9f --- /dev/null +++ b/queue-3.0/sysfs-fix-memory-leak-in-sysfs_sd_setsecdata.patch @@ -0,0 +1,90 @@ +From 93518dd2ebafcc761a8637b2877008cfd748c202 Mon Sep 17 00:00:00 2001 +From: Masami Ichikawa +Date: Tue, 21 Feb 2012 07:43:50 +0900 +Subject: sysfs: Fix memory leak in sysfs_sd_setsecdata(). + +From: Masami Ichikawa + +commit 93518dd2ebafcc761a8637b2877008cfd748c202 upstream. + +This patch fixies follwing two memory leak patterns that reported by kmemleak. +sysfs_sd_setsecdata() is called during sys_lsetxattr() operation. +It checks sd->s_iattr is NULL or not. Then if it is NULL, it calls +sysfs_init_inode_attrs() to allocate memory. +That code is this. + +iattrs = sd->s_iattr; +if (!iattrs) + iattrs = sysfs_init_inode_attrs(sd); + +The iattrs recieves sysfs_init_inode_attrs()'s result, but sd->s_iattr +doesn't know the address. so it needs to set correct address to +sd->s_iattr to free memory in other function. + +unreferenced object 0xffff880250b73e60 (size 32): + comm "systemd", pid 1, jiffies 4294683888 (age 94.553s) + hex dump (first 32 bytes): + 73 79 73 74 65 6d 5f 75 3a 6f 62 6a 65 63 74 5f system_u:object_ + 72 3a 73 79 73 66 73 5f 74 3a 73 30 00 00 00 00 r:sysfs_t:s0.... + backtrace: + [] kmemleak_alloc+0x73/0x98 + [] __kmalloc+0x100/0x12c + [] context_struct_to_string+0x106/0x210 + [] security_sid_to_context_core+0x10b/0x129 + [] security_sid_to_context+0x10/0x12 + [] selinux_inode_getsecurity+0x7d/0xa8 + [] selinux_inode_getsecctx+0x22/0x2e + [] security_inode_getsecctx+0x16/0x18 + [] sysfs_setxattr+0x96/0x117 + [] __vfs_setxattr_noperm+0x73/0xd9 + [] vfs_setxattr+0x83/0xa1 + [] setxattr+0xcf/0x101 + [] sys_lsetxattr+0x6a/0x8f + [] system_call_fastpath+0x16/0x1b + [] 0xffffffffffffffff +unreferenced object 0xffff88024163c5a0 (size 96): + comm "systemd", pid 1, jiffies 4294683888 (age 94.553s) + hex dump (first 32 bytes): + 00 00 00 00 ed 41 00 00 00 00 00 00 00 00 00 00 .....A.......... + 00 00 00 00 00 00 00 00 0c 64 42 4f 00 00 00 00 .........dBO.... + backtrace: + [] kmemleak_alloc+0x73/0x98 + [] kmem_cache_alloc_trace+0xc4/0xee + [] sysfs_init_inode_attrs+0x2a/0x83 + [] sysfs_setxattr+0xbf/0x117 + [] __vfs_setxattr_noperm+0x73/0xd9 + [] vfs_setxattr+0x83/0xa1 + [] setxattr+0xcf/0x101 + [] sys_lsetxattr+0x6a/0x8f + [] system_call_fastpath+0x16/0x1b + [] 0xffffffffffffffff +` + +Signed-off-by: Masami Ichikawa +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/inode.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/fs/sysfs/inode.c ++++ b/fs/sysfs/inode.c +@@ -136,12 +136,13 @@ static int sysfs_sd_setsecdata(struct sy + void *old_secdata; + size_t old_secdata_len; + +- iattrs = sd->s_iattr; +- if (!iattrs) +- iattrs = sysfs_init_inode_attrs(sd); +- if (!iattrs) +- return -ENOMEM; ++ if (!sd->s_iattr) { ++ sd->s_iattr = sysfs_init_inode_attrs(sd); ++ if (!sd->s_iattr) ++ return -ENOMEM; ++ } + ++ iattrs = sd->s_iattr; + old_secdata = iattrs->ia_secdata; + old_secdata_len = iattrs->ia_secdata_len; + diff --git a/queue-3.0/tty-moxa-fix-bit-test-in-moxa_start.patch b/queue-3.0/tty-moxa-fix-bit-test-in-moxa_start.patch new file mode 100644 index 00000000000..76897b4a2fd --- /dev/null +++ b/queue-3.0/tty-moxa-fix-bit-test-in-moxa_start.patch @@ -0,0 +1,32 @@ +From 58112dfbfe02d803566a2c6c8bd97b5fa3c62cdc Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 7 Mar 2012 13:05:00 +0300 +Subject: tty: moxa: fix bit test in moxa_start() + +From: Dan Carpenter + +commit 58112dfbfe02d803566a2c6c8bd97b5fa3c62cdc upstream. + +This is supposed to be doing a shift before the comparison instead of +just doing a bitwise AND directly. The current code means the start() +just returns without doing anything. + +Signed-off-by: Dan Carpenter +Acked-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/moxa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/moxa.c ++++ b/drivers/tty/moxa.c +@@ -1330,7 +1330,7 @@ static void moxa_start(struct tty_struct + if (ch == NULL) + return; + +- if (!(ch->statusflags & TXSTOPPED)) ++ if (!test_bit(TXSTOPPED, &ch->statusflags)) + return; + + MoxaPortTxEnable(ch); diff --git a/queue-3.0/tty-wrong-unicode-value-copied-in-con_set_unimap.patch b/queue-3.0/tty-wrong-unicode-value-copied-in-con_set_unimap.patch new file mode 100644 index 00000000000..11942a1b928 --- /dev/null +++ b/queue-3.0/tty-wrong-unicode-value-copied-in-con_set_unimap.patch @@ -0,0 +1,117 @@ +From 4a4c61b7ce26bfc9d49ea4bd121d52114bad9f99 Mon Sep 17 00:00:00 2001 +From: Liz Clark +Date: Thu, 15 Mar 2012 10:33:29 -0700 +Subject: TTY: Wrong unicode value copied in con_set_unimap() + +From: Liz Clark + +commit 4a4c61b7ce26bfc9d49ea4bd121d52114bad9f99 upstream. + +Bugzilla 40012: PIO_UNIMAP bug: error updating Unicode-to-font map +https://bugzilla.kernel.org/show_bug.cgi?id=40012 + +The unicode font map for the virtual console is a 32x32x64 table which +allocates rows dynamically as entries are added. The unicode value +increases sequentially and should count all entries even in empty +rows. The defect is when copying the unicode font map in con_set_unimap(), +the unicode value is not incremented properly. The wrong unicode value +is entered in the new font map. + +Signed-off-by: Liz Clark +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/consolemap.c | 51 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 43 insertions(+), 8 deletions(-) + +--- a/drivers/tty/vt/consolemap.c ++++ b/drivers/tty/vt/consolemap.c +@@ -516,6 +516,7 @@ int con_set_unimap(struct vc_data *vc, u + int err = 0, err1, i; + struct uni_pagedir *p, *q; + ++ /* Save original vc_unipagdir_loc in case we allocate a new one */ + p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + if (p->readonly) return -EIO; + +@@ -528,26 +529,57 @@ int con_set_unimap(struct vc_data *vc, u + err1 = con_clear_unimap(vc, NULL); + if (err1) return err1; + ++ /* ++ * Since refcount was > 1, con_clear_unimap() allocated a ++ * a new uni_pagedir for this vc. Re: p != q ++ */ + q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; +- for (i = 0, l = 0; i < 32; i++) ++ ++ /* ++ * uni_pgdir is a 32*32*64 table with rows allocated ++ * when its first entry is added. The unicode value must ++ * still be incremented for empty rows. We are copying ++ * entries from "p" (old) to "q" (new). ++ */ ++ l = 0; /* unicode value */ ++ for (i = 0; i < 32; i++) + if ((p1 = p->uni_pgdir[i])) + for (j = 0; j < 32; j++) +- if ((p2 = p1[j])) ++ if ((p2 = p1[j])) { + for (k = 0; k < 64; k++, l++) + if (p2[k] != 0xffff) { ++ /* ++ * Found one, copy entry for unicode ++ * l with fontpos value p2[k]. ++ */ + err1 = con_insert_unipair(q, l, p2[k]); + if (err1) { + p->refcount++; + *vc->vc_uni_pagedir_loc = (unsigned long)p; + con_release_unimap(q); + kfree(q); +- return err1; ++ return err1; + } +- } +- p = q; +- } else if (p == dflt) ++ } ++ } else { ++ /* Account for row of 64 empty entries */ ++ l += 64; ++ } ++ else ++ /* Account for empty table */ ++ l += 32 * 64; ++ ++ /* ++ * Finished copying font table, set vc_uni_pagedir to new table ++ */ ++ p = q; ++ } else if (p == dflt) { + dflt = NULL; +- ++ } ++ ++ /* ++ * Insert user specified unicode pairs into new table. ++ */ + while (ct--) { + unsigned short unicode, fontpos; + __get_user(unicode, &list->unicode); +@@ -557,11 +589,14 @@ int con_set_unimap(struct vc_data *vc, u + list++; + } + ++ /* ++ * Merge with fontmaps of any other virtual consoles. ++ */ + if (con_unify_unimap(vc, p)) + return err; + + for (i = 0; i <= 3; i++) +- set_inverse_transl(vc, p, i); /* Update all inverse translations */ ++ set_inverse_transl(vc, p, i); /* Update inverse translations */ + set_inverse_trans_unicode(vc, p); + + return err; diff --git a/queue-3.0/usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch b/queue-3.0/usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch new file mode 100644 index 00000000000..ba2b980ebbc --- /dev/null +++ b/queue-3.0/usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch @@ -0,0 +1,46 @@ +From e90fc3cb087ce5c5f81e814358222cd6d197b5db Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Thu, 16 Feb 2012 09:41:52 +0800 +Subject: usb: Fix build error due to dma_mask is not at pdev_archdata at ARM + +From: Peter Chen + +commit e90fc3cb087ce5c5f81e814358222cd6d197b5db upstream. + +When build i.mx platform with imx_v6_v7_defconfig, and after adding +USB Gadget support, it has below build error: + +CC drivers/usb/host/fsl-mph-dr-of.o +drivers/usb/host/fsl-mph-dr-of.c: In function 'fsl_usb2_device_register': +drivers/usb/host/fsl-mph-dr-of.c:97: error: 'struct pdev_archdata' +has no member named 'dma_mask' + +It has discussed at: http://www.spinics.net/lists/linux-usb/msg57302.html + +For PowerPC, there is dma_mask at struct pdev_archdata, but there is +no dma_mask at struct pdev_archdata for ARM. The pdev_archdata is +related to specific platform, it should NOT be accessed by +cross platform drivers, like USB. + +The code for pdev_archdata should be useless, as for PowerPC, +it has already gotten the value for pdev->dev.dma_mask at function +arch_setup_pdev_archdata of arch/powerpc/kernel/setup-common.c. + +Tested-by: Ramneek Mehresh +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/fsl-mph-dr-of.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/host/fsl-mph-dr-of.c ++++ b/drivers/usb/host/fsl-mph-dr-of.c +@@ -93,7 +93,6 @@ struct platform_device * __devinit fsl_u + pdev->dev.parent = &ofdev->dev; + + pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask; +- pdev->dev.dma_mask = &pdev->archdata.dma_mask; + *pdev->dev.dma_mask = *ofdev->dev.dma_mask; + + retval = platform_device_add_data(pdev, pdata, sizeof(*pdata)); diff --git a/queue-3.0/usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch b/queue-3.0/usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch new file mode 100644 index 00000000000..560e0b4fb4b --- /dev/null +++ b/queue-3.0/usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch @@ -0,0 +1,131 @@ +From c5cc5ed86667d4ae74fe40ee4ed893f4b46aba05 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Thu, 16 Feb 2012 09:36:25 +0800 +Subject: usb: fsl_udc_core: Fix scheduling while atomic dump message + +From: Peter Chen + +commit c5cc5ed86667d4ae74fe40ee4ed893f4b46aba05 upstream. + +When loading g_ether gadget, there is below message: + +Backtrace: +[<80012248>] (dump_backtrace+0x0/0x10c) from [<803cb42c>] (dump_stack+0x18/0x1c) +r7:00000000 r6:80512000 r5:8052bef8 r4:80513f30 +[<803cb414>] (dump_stack+0x0/0x1c) from [<8000feb4>] (show_regs+0x44/0x50) +[<8000fe70>] (show_regs+0x0/0x50) from [<8004c840>] (__schedule_bug+0x68/0x84) +r5:8052bef8 r4:80513f30 +[<8004c7d8>] (__schedule_bug+0x0/0x84) from [<803cd0e4>] (__schedule+0x4b0/0x528) +r5:8052bef8 r4:809aad00 +[<803ccc34>] (__schedule+0x0/0x528) from [<803cd214>] (_cond_resched+0x44/0x58) +[<803cd1d0>] (_cond_resched+0x0/0x58) from [<800a9488>] (dma_pool_alloc+0x184/0x250) + r5:9f9b4000 r4:9fb4fb80 + [<800a9304>] (dma_pool_alloc+0x0/0x250) from [<802a8ad8>] (fsl_req_to_dtd+0xac/0x180) +[<802a8a2c>] (fsl_req_to_dtd+0x0/0x180) from [<802a8ce4>] (fsl_ep_queue+0x138/0x274) +[<802a8bac>] (fsl_ep_queue+0x0/0x274) from [<7f004328>] (composite_setup+0x2d4/0xfac [g_ether]) +[<7f004054>] (composite_setup+0x0/0xfac [g_ether]) from [<802a9bb4>] (fsl_udc_irq+0x8dc/0xd38) +[<802a92d8>] (fsl_udc_irq+0x0/0xd38) from [<800704f8>] (handle_irq_event_percpu+0x54/0x188) +[<800704a4>] (handle_irq_event_percpu+0x0/0x188) from [<80070674>] (handle_irq_event+0x48/0x68) +[<8007062c>] (handle_irq_event+0x0/0x68) from [<800738ec>] (handle_level_irq+0xb4/0x138) + r5:80514f94 r4:80514f40 + [<80073838>] (handle_level_irq+0x0/0x138) from [<8006ffa4>] (generic_handle_irq+0x38/0x44) + r7:00000012 r6:80510b1c r5:80529860 r4:80512000 + [<8006ff6c>] (generic_handle_irq+0x0/0x44) from [<8000f4c4>] (handle_IRQ+0x54/0xb4) +[<8000f470>] (handle_IRQ+0x0/0xb4) from [<800085b8>] (tzic_handle_irq+0x64/0x94) + r9:412fc085 r8:00000000 r7:80513f30 r6:00000001 r5:00000000 + r4:00000000 + [<80008554>] (tzic_handle_irq+0x0/0x94) from [<8000e680>] (__irq_svc+0x40/0x60) + +The reason of above dump message is calling dma_poll_alloc with can-schedule +mem_flags at atomic context. + +To fix this problem, below changes are made: +- fsl_req_to_dtd doesn't need to be protected by spin_lock_irqsave, +as struct usb_request can be access at process context. Move lock +to beginning of hardware visit (fsl_queue_td). +- Change the memory flag which using to allocate dTD descriptor buffer, +the memory flag can be from gadget layer. + +It is tested at i.mx51 bbg board with g_mass_storage, g_ether, g_serial. + +Signed-off-by: Peter Chen +Acked-by: Li Yang +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/fsl_udc_core.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/usb/gadget/fsl_udc_core.c ++++ b/drivers/usb/gadget/fsl_udc_core.c +@@ -767,7 +767,7 @@ out: + * @is_last: return flag if it is the last dTD of the request + * return: pointer to the built dTD */ + static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, +- dma_addr_t *dma, int *is_last) ++ dma_addr_t *dma, int *is_last, gfp_t gfp_flags) + { + u32 swap_temp; + struct ep_td_struct *dtd; +@@ -776,7 +776,7 @@ static struct ep_td_struct *fsl_build_dt + *length = min(req->req.length - req->req.actual, + (unsigned)EP_MAX_LENGTH_TRANSFER); + +- dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); ++ dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); + if (dtd == NULL) + return dtd; + +@@ -826,7 +826,7 @@ static struct ep_td_struct *fsl_build_dt + } + + /* Generate dtd chain for a request */ +-static int fsl_req_to_dtd(struct fsl_req *req) ++static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) + { + unsigned count; + int is_last; +@@ -835,7 +835,7 @@ static int fsl_req_to_dtd(struct fsl_req + dma_addr_t dma; + + do { +- dtd = fsl_build_dtd(req, &count, &dma, &is_last); ++ dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); + if (dtd == NULL) + return -ENOMEM; + +@@ -909,13 +909,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct + req->req.actual = 0; + req->dtd_count = 0; + +- spin_lock_irqsave(&udc->lock, flags); +- + /* build dtds and push them to device queue */ +- if (!fsl_req_to_dtd(req)) { ++ if (!fsl_req_to_dtd(req, gfp_flags)) { ++ spin_lock_irqsave(&udc->lock, flags); + fsl_queue_td(ep, req); + } else { +- spin_unlock_irqrestore(&udc->lock, flags); + return -ENOMEM; + } + +@@ -1294,7 +1292,7 @@ static int ep0_prime_status(struct fsl_u + ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + req->mapped = 1; + +- if (fsl_req_to_dtd(req) == 0) ++ if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) + fsl_queue_td(ep, req); + else + return -ENOMEM; +@@ -1378,7 +1376,7 @@ static void ch9getstatus(struct fsl_udc + req->mapped = 1; + + /* prime the data phase */ +- if ((fsl_req_to_dtd(req) == 0)) ++ if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) + fsl_queue_td(ep, req); + else /* no mem */ + goto stall; diff --git a/queue-3.0/usb-serial-fix-console-error-reporting.patch b/queue-3.0/usb-serial-fix-console-error-reporting.patch new file mode 100644 index 00000000000..8f01cb5b25c --- /dev/null +++ b/queue-3.0/usb-serial-fix-console-error-reporting.patch @@ -0,0 +1,34 @@ +From 548dd4b6da8a8e428453d55f7fa7b8a46498d147 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 10 Feb 2012 13:20:49 +0100 +Subject: USB: serial: fix console error reporting + +From: Johan Hovold + +commit 548dd4b6da8a8e428453d55f7fa7b8a46498d147 upstream. + +Do not report errors in write path if port is used as a console as this +may trigger the same error (and error report) resulting in a loop. + +Reported-by: Stephen Hemminger +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/generic.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -215,8 +215,10 @@ retry: + clear_bit(i, &port->write_urbs_free); + result = usb_submit_urb(urb, GFP_ATOMIC); + if (result) { +- dev_err(&port->dev, "%s - error submitting urb: %d\n", ++ if (!port->port.console) { ++ dev_err(&port->dev, "%s - error submitting urb: %d\n", + __func__, result); ++ } + set_bit(i, &port->write_urbs_free); + spin_lock_irqsave(&port->lock, flags); + port->tx_bytes -= count;