From: Greg Kroah-Hartman Date: Mon, 23 Sep 2013 22:46:18 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.97~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66556dbdab9b4d5ced911649d0898fba05f69ae4;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: asoc-wm8960-fix-pll-register-writes.patch rculist-list_first_or_null_rcu-should-use-list_entry_rcu.patch usb-cdc-wdm-fix-race-between-interrupt-handler-and-tasklet.patch usb-config-desc.blength-may-not-exceed-amount-of-data-returned-by-the-device.patch usb-mos7720-fix-big-endian-control-requests.patch usb-mos7720-use-gfp_atomic-under-spinlock.patch --- diff --git a/queue-3.0/asoc-wm8960-fix-pll-register-writes.patch b/queue-3.0/asoc-wm8960-fix-pll-register-writes.patch new file mode 100644 index 00000000000..153eda0b2b6 --- /dev/null +++ b/queue-3.0/asoc-wm8960-fix-pll-register-writes.patch @@ -0,0 +1,35 @@ +From 85fa532b6ef920b32598df86b194571a7059a77c Mon Sep 17 00:00:00 2001 +From: Mike Dyer +Date: Fri, 16 Aug 2013 18:36:28 +0100 +Subject: ASoC: wm8960: Fix PLL register writes + +From: Mike Dyer + +commit 85fa532b6ef920b32598df86b194571a7059a77c upstream. + +Bit 9 of PLL2,3 and 4 is reserved as '0'. The 24bit fractional part +should be split across each register in 8bit chunks. + +Signed-off-by: Mike Dyer +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm8960.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/sound/soc/codecs/wm8960.c ++++ b/sound/soc/codecs/wm8960.c +@@ -801,9 +801,9 @@ static int wm8960_set_dai_pll(struct snd + if (pll_div.k) { + reg |= 0x20; + +- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); +- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); +- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); ++ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); ++ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); ++ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); + } + snd_soc_write(codec, WM8960_PLL1, reg); + diff --git a/queue-3.0/rculist-list_first_or_null_rcu-should-use-list_entry_rcu.patch b/queue-3.0/rculist-list_first_or_null_rcu-should-use-list_entry_rcu.patch new file mode 100644 index 00000000000..8e6426c1d7d --- /dev/null +++ b/queue-3.0/rculist-list_first_or_null_rcu-should-use-list_entry_rcu.patch @@ -0,0 +1,68 @@ +From c34ac00caefbe49d40058ae7200bd58725cebb45 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Fri, 28 Jun 2013 10:34:48 -0700 +Subject: rculist: list_first_or_null_rcu() should use list_entry_rcu() + +From: Tejun Heo + +commit c34ac00caefbe49d40058ae7200bd58725cebb45 upstream. + +list_first_or_null() should test whether the list is empty and return +pointer to the first entry if not in a RCU safe manner. It's broken +in several ways. + +* It compares __kernel @__ptr with __rcu @__next triggering the + following sparse warning. + + net/core/dev.c:4331:17: error: incompatible types in comparison expression (different address spaces) + +* It doesn't perform rcu_dereference*() and computes the entry address + using container_of() directly from the __rcu pointer which is + inconsitent with other rculist interface. As a result, all three + in-kernel users - net/core/dev.c, macvlan, cgroup - are buggy. They + dereference the pointer w/o going through read barrier. + +* While ->next dereference passes through list_next_rcu(), the + compiler is still free to fetch ->next more than once and thus + nullify the "__ptr != __next" condition check. + +Fix it by making list_first_or_null_rcu() dereference ->next directly +using ACCESS_ONCE() and then use list_entry_rcu() on it like other +rculist accessors. + +v2: Paul pointed out that the compiler may fetch the pointer more than + once nullifying the condition check. ACCESS_ONCE() added on + ->next dereference. + +v3: Restored () around macro param which was accidentally removed. + Spotted by Paul. + +Signed-off-by: Tejun Heo +Reported-by: Fengguang Wu +Cc: Dipankar Sarma +Cc: "Paul E. McKenney" +Cc: "David S. Miller" +Cc: Li Zefan +Cc: Patrick McHardy +Signed-off-by: Paul E. McKenney +Reviewed-by: Josh Triplett +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/rculist.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/include/linux/rculist.h ++++ b/include/linux/rculist.h +@@ -254,8 +254,9 @@ static inline void list_splice_init_rcu( + */ + #define list_first_or_null_rcu(ptr, type, member) \ + ({struct list_head *__ptr = (ptr); \ +- struct list_head __rcu *__next = list_next_rcu(__ptr); \ +- likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ ++ struct list_head *__next = ACCESS_ONCE(__ptr->next); \ ++ likely(__ptr != __next) ? \ ++ list_entry_rcu(__next, type, member) : NULL; \ + }) + + /** diff --git a/queue-3.0/series b/queue-3.0/series index b04a34f74b6..ee51b2bd709 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -6,3 +6,9 @@ arm-pci-versatile-fix-smap-register-offsets.patch usb-xhci-disable-runtime-pm-suspend-for-quirky-controllers.patch cifs-ensure-that-srv_mutex-is-held-when-dealing-with-ssocket-pointer.patch staging-comedi-dt282x-dt282x_ai_insn_read-always-fails.patch +usb-mos7720-use-gfp_atomic-under-spinlock.patch +usb-mos7720-fix-big-endian-control-requests.patch +usb-cdc-wdm-fix-race-between-interrupt-handler-and-tasklet.patch +usb-config-desc.blength-may-not-exceed-amount-of-data-returned-by-the-device.patch +rculist-list_first_or_null_rcu-should-use-list_entry_rcu.patch +asoc-wm8960-fix-pll-register-writes.patch diff --git a/queue-3.0/usb-cdc-wdm-fix-race-between-interrupt-handler-and-tasklet.patch b/queue-3.0/usb-cdc-wdm-fix-race-between-interrupt-handler-and-tasklet.patch new file mode 100644 index 00000000000..edba18becbd --- /dev/null +++ b/queue-3.0/usb-cdc-wdm-fix-race-between-interrupt-handler-and-tasklet.patch @@ -0,0 +1,63 @@ +From 6dd433e6cf2475ce8abec1b467720858c24450eb Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Tue, 6 Aug 2013 14:22:59 +0200 +Subject: USB: cdc-wdm: fix race between interrupt handler and tasklet + +From: Oliver Neukum + +commit 6dd433e6cf2475ce8abec1b467720858c24450eb upstream. + +Both could want to submit the same URB. Some checks of the flag +intended to prevent that were missing. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -171,6 +171,7 @@ skip_error: + static void wdm_int_callback(struct urb *urb) + { + int rv = 0; ++ int responding; + int status = urb->status; + struct wdm_device *desc; + struct usb_ctrlrequest *req; +@@ -244,8 +245,8 @@ static void wdm_int_callback(struct urb + desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + spin_lock(&desc->iuspin); + clear_bit(WDM_READ, &desc->flags); +- set_bit(WDM_RESPONDING, &desc->flags); +- if (!test_bit(WDM_DISCONNECTING, &desc->flags) ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); ++ if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { + rv = usb_submit_urb(desc->response, GFP_ATOMIC); + dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", +@@ -635,16 +636,20 @@ static void wdm_rxwork(struct work_struc + { + struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); + unsigned long flags; +- int rv; ++ int rv = 0; ++ int responding; + + spin_lock_irqsave(&desc->iuspin, flags); + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + spin_unlock_irqrestore(&desc->iuspin, flags); + } else { ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); +- rv = usb_submit_urb(desc->response, GFP_KERNEL); ++ if (!responding) ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + if (rv < 0 && rv != -EPERM) { + spin_lock_irqsave(&desc->iuspin, flags); ++ clear_bit(WDM_RESPONDING, &desc->flags); + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) + schedule_work(&desc->rxwork); + spin_unlock_irqrestore(&desc->iuspin, flags); diff --git a/queue-3.0/usb-config-desc.blength-may-not-exceed-amount-of-data-returned-by-the-device.patch b/queue-3.0/usb-config-desc.blength-may-not-exceed-amount-of-data-returned-by-the-device.patch new file mode 100644 index 00000000000..9156194eb0c --- /dev/null +++ b/queue-3.0/usb-config-desc.blength-may-not-exceed-amount-of-data-returned-by-the-device.patch @@ -0,0 +1,33 @@ +From b4f17a488ae2e09bfcf95c0e0b4219c246f1116a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 3 Aug 2013 16:37:48 +0200 +Subject: usb: config->desc.bLength may not exceed amount of data returned by the device + +From: Hans de Goede + +commit b4f17a488ae2e09bfcf95c0e0b4219c246f1116a upstream. + +While reading the config parsing code I noticed this check is missing, without +this check config->desc.wTotalLength can end up with a value larger then the +dev->rawdescriptors length for the config, and when userspace then tries to +get the rawdescriptors bad things may happen. + +Signed-off-by: Hans de Goede +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -424,7 +424,8 @@ static int usb_parse_configuration(struc + + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + if (config->desc.bDescriptorType != USB_DT_CONFIG || +- config->desc.bLength < USB_DT_CONFIG_SIZE) { ++ config->desc.bLength < USB_DT_CONFIG_SIZE || ++ config->desc.bLength > size) { + dev_err(ddev, "invalid descriptor for config index %d: " + "type = 0x%X, length = %d\n", cfgidx, + config->desc.bDescriptorType, config->desc.bLength); diff --git a/queue-3.0/usb-mos7720-fix-big-endian-control-requests.patch b/queue-3.0/usb-mos7720-fix-big-endian-control-requests.patch new file mode 100644 index 00000000000..e6431b4b55d --- /dev/null +++ b/queue-3.0/usb-mos7720-fix-big-endian-control-requests.patch @@ -0,0 +1,33 @@ +From 3b716caf190ccc6f2a09387210e0e6a26c1d81a4 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 19 Aug 2013 13:05:45 +0200 +Subject: USB: mos7720: fix big-endian control requests + +From: Johan Hovold + +commit 3b716caf190ccc6f2a09387210e0e6a26c1d81a4 upstream. + +Fix endianess bugs in parallel-port code which caused corrupt +control-requests to be issued on big-endian machines. + +Reported-by: kbuild test robot +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mos7720.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(st + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; +- urbtrack->setup->wValue = get_reg_value(reg, dummy); +- urbtrack->setup->wIndex = get_reg_index(reg); ++ urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); ++ urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); + urbtrack->setup->wLength = 0; + usb_fill_control_urb(urbtrack->urb, usbdev, + usb_sndctrlpipe(usbdev, 0), diff --git a/queue-3.0/usb-mos7720-use-gfp_atomic-under-spinlock.patch b/queue-3.0/usb-mos7720-use-gfp_atomic-under-spinlock.patch new file mode 100644 index 00000000000..2b643e5f5b6 --- /dev/null +++ b/queue-3.0/usb-mos7720-use-gfp_atomic-under-spinlock.patch @@ -0,0 +1,31 @@ +From d0bd9a41186e076ea543c397ad8a67a6cf604b55 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 16 Aug 2013 10:16:59 +0300 +Subject: USB: mos7720: use GFP_ATOMIC under spinlock + +From: Dan Carpenter + +commit d0bd9a41186e076ea543c397ad8a67a6cf604b55 upstream. + +The write_parport_reg_nonblock() function shouldn't sleep because it's +called with spinlocks held. + +Signed-off-by: Dan Carpenter +Acked-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mos7720.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(st + kfree(urbtrack); + return -ENOMEM; + } +- urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); ++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack);