From: Greg Kroah-Hartman Date: Sun, 8 Dec 2013 20:02:11 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.4.74~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=56a8ea6855b0c003ea3f340a0aa8de61619a6efa;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: asoc-wm8731-fix-dsp-mode-configuration.patch asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch --- diff --git a/queue-3.10/asoc-wm8731-fix-dsp-mode-configuration.patch b/queue-3.10/asoc-wm8731-fix-dsp-mode-configuration.patch new file mode 100644 index 00000000000..9c215591f68 --- /dev/null +++ b/queue-3.10/asoc-wm8731-fix-dsp-mode-configuration.patch @@ -0,0 +1,37 @@ +From b4af6ef99a60c5b56df137d7accd81ba1ee1254e Mon Sep 17 00:00:00 2001 +From: Bo Shen +Date: Tue, 3 Dec 2013 18:04:54 +0800 +Subject: ASoC: wm8731: fix dsp mode configuration + +From: Bo Shen + +commit b4af6ef99a60c5b56df137d7accd81ba1ee1254e upstream. + +According to WM8731 "PD, Rev 4.9 October 2012" datasheet, when it +works in DSP mode A, LRP = 1, while works in DSP mode B, LRP = 0. +So, fix LRP for DSP mode as the datesheet specification. + +Signed-off-by: Bo Shen +Acked-by: Charles Keepax +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm8731.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/soc/codecs/wm8731.c ++++ b/sound/soc/codecs/wm8731.c +@@ -407,10 +407,10 @@ static int wm8731_set_dai_fmt(struct snd + iface |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: +- iface |= 0x0003; ++ iface |= 0x0013; + break; + case SND_SOC_DAIFMT_DSP_B: +- iface |= 0x0013; ++ iface |= 0x0003; + break; + default: + return -EINVAL; diff --git a/queue-3.10/asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch b/queue-3.10/asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch new file mode 100644 index 00000000000..67bf2335c5b --- /dev/null +++ b/queue-3.10/asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch @@ -0,0 +1,30 @@ +From 2ab2b74277a86afe0dd92976db695a2bb8b93366 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Fri, 22 Nov 2013 14:17:18 +0000 +Subject: ASoC: wm8990: Mark the register map as dirty when powering down + +From: Mark Brown + +commit 2ab2b74277a86afe0dd92976db695a2bb8b93366 upstream. + +Otherwise we'll skip sync on resume. + +Signed-off-by: Mark Brown +Acked-by: Charles Keepax +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm8990.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/codecs/wm8990.c ++++ b/sound/soc/codecs/wm8990.c +@@ -1264,6 +1264,8 @@ static int wm8990_set_bias_level(struct + + /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ + snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); ++ ++ codec->cache_sync = 1; + break; + } + diff --git a/queue-3.10/can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch b/queue-3.10/can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch new file mode 100644 index 00000000000..20a7866d089 --- /dev/null +++ b/queue-3.10/can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch @@ -0,0 +1,74 @@ +From e35d46adc49b469fd92bdb64fea8af93640e6651 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Sun, 24 Nov 2013 23:31:24 +0100 +Subject: can: c_can: don't call pm_runtime_get_sync() from interrupt context + +From: Marc Kleine-Budde + +commit e35d46adc49b469fd92bdb64fea8af93640e6651 upstream. + +The c_can driver contians a callpath (c_can_poll -> c_can_state_change -> +c_can_get_berr_counter) which may call pm_runtime_get_sync() from the IRQ +handler, which is not allowed and results in "BUG: scheduling while atomic". + +This problem is fixed by introducing __c_can_get_berr_counter, which will not +call pm_runtime_get_sync(). + +Reported-by: Andrew Glen +Tested-by: Andrew Glen +Signed-off-by: Andrew Glen +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/c_can/c_can.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -712,22 +712,31 @@ static int c_can_set_mode(struct net_dev + return 0; + } + +-static int c_can_get_berr_counter(const struct net_device *dev, +- struct can_berr_counter *bec) ++static int __c_can_get_berr_counter(const struct net_device *dev, ++ struct can_berr_counter *bec) + { + unsigned int reg_err_counter; + struct c_can_priv *priv = netdev_priv(dev); + +- c_can_pm_runtime_get_sync(priv); +- + reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); + bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> + ERR_CNT_REC_SHIFT; + bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; + ++ return 0; ++} ++ ++static int c_can_get_berr_counter(const struct net_device *dev, ++ struct can_berr_counter *bec) ++{ ++ struct c_can_priv *priv = netdev_priv(dev); ++ int err; ++ ++ c_can_pm_runtime_get_sync(priv); ++ err = __c_can_get_berr_counter(dev, bec); + c_can_pm_runtime_put_sync(priv); + +- return 0; ++ return err; + } + + /* +@@ -872,7 +881,7 @@ static int c_can_handle_state_change(str + if (unlikely(!skb)) + return 0; + +- c_can_get_berr_counter(dev, &bec); ++ __c_can_get_berr_counter(dev, &bec); + reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); + rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> + ERR_CNT_RP_SHIFT; diff --git a/queue-3.10/can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch b/queue-3.10/can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch new file mode 100644 index 00000000000..fd23f063044 --- /dev/null +++ b/queue-3.10/can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch @@ -0,0 +1,74 @@ +From 2fea6cd303c0d0cd9067da31d873b6a6d5bd75e7 Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Thu, 21 Nov 2013 18:03:07 +0100 +Subject: can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value + +From: Oliver Hartkopp + +commit 2fea6cd303c0d0cd9067da31d873b6a6d5bd75e7 upstream. + +This patch fixes the issue that the sja1000_interrupt() function may have +returned IRQ_NONE without processing the optional pre_irq() and post_irq() +function before. Further the irq processing counter 'n' is moved to the end of +the while statement to return correct IRQ_[NONE|HANDLED] values at error +conditions. + +Reported-by: Wolfgang Grandegger +Acked-by: Wolfgang Grandegger +Signed-off-by: Oliver Hartkopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/sja1000/sja1000.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/net/can/sja1000/sja1000.c ++++ b/drivers/net/can/sja1000/sja1000.c +@@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, v + uint8_t isrc, status; + int n = 0; + +- /* Shared interrupts and IRQ off? */ +- if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF) +- return IRQ_NONE; +- + if (priv->pre_irq) + priv->pre_irq(priv); + ++ /* Shared interrupts and IRQ off? */ ++ if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF) ++ goto out; ++ + while ((isrc = priv->read_reg(priv, SJA1000_IR)) && + (n < SJA1000_MAX_IRQ)) { +- n++; ++ + status = priv->read_reg(priv, SJA1000_SR); + /* check for absent controller due to hw unplug */ + if (status == 0xFF && sja1000_is_absent(priv)) +- return IRQ_NONE; ++ goto out; + + if (isrc & IRQ_WUI) + netdev_warn(dev, "wakeup interrupt\n"); +@@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, v + status = priv->read_reg(priv, SJA1000_SR); + /* check for absent controller */ + if (status == 0xFF && sja1000_is_absent(priv)) +- return IRQ_NONE; ++ goto out; + } + } + if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { +@@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, v + if (sja1000_err(dev, isrc, status)) + break; + } ++ n++; + } +- ++out: + if (priv->post_irq) + priv->post_irq(priv); + diff --git a/queue-3.10/series b/queue-3.10/series index e09f667c479..f42a4941253 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -13,3 +13,8 @@ arm-footbridge-fix-ebsa285-leds.patch arm-at91-sama5d3-reduce-twi-internal-clock-frequency.patch arm-mvebu-use-the-virtual-cpu-registers-to-access-coherency-registers.patch arm-mvebu-re-enable-pcie-on-armada-370-db.patch +asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch +asoc-wm8731-fix-dsp-mode-configuration.patch +vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch +can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch +can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch diff --git a/queue-3.10/vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch b/queue-3.10/vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch new file mode 100644 index 00000000000..aed9775527f --- /dev/null +++ b/queue-3.10/vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch @@ -0,0 +1,133 @@ +From b0d8d2292160bb63de1972361ebed100c64b5b37 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Mon, 2 Dec 2013 09:44:51 -0800 +Subject: vfs: fix subtle use-after-free of pipe_inode_info + +From: Linus Torvalds + +commit b0d8d2292160bb63de1972361ebed100c64b5b37 upstream. + +The pipe code was trying (and failing) to be very careful about freeing +the pipe info only after the last access, with a pattern like: + + spin_lock(&inode->i_lock); + if (!--pipe->files) { + inode->i_pipe = NULL; + kill = 1; + } + spin_unlock(&inode->i_lock); + __pipe_unlock(pipe); + if (kill) + free_pipe_info(pipe); + +where the final freeing is done last. + +HOWEVER. The above is actually broken, because while the freeing is +done at the end, if we have two racing processes releasing the pipe +inode info, the one that *doesn't* free it will decrement the ->files +count, and unlock the inode i_lock, but then still use the +"pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)". + +This is *very* hard to trigger in practice, since the race window is +very small, and adding debug options seems to just hide it by slowing +things down. + +Simon originally reported this way back in July as an Oops in +kmem_cache_allocate due to a single bit corruption (due to the final +"spin_unlock(pipe->mutex.wait_lock)" incrementing a field in a different +allocation that had re-used the free'd pipe-info), it's taken this long +to figure out. + +Since the 'pipe->files' accesses aren't even protected by the pipe lock +(we very much use the inode lock for that), the simple solution is to +just drop the pipe lock early. And since there were two users of this +pattern, create a helper function for it. + +Introduced commit ba5bb147330a ("pipe: take allocation and freeing of +pipe_inode_info out of ->i_mutex"). + +Reported-by: Simon Kirby +Reported-by: Ian Applegate +Acked-by: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pipe.c | 39 +++++++++++++++++++-------------------- + 1 file changed, 19 insertions(+), 20 deletions(-) + +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -726,11 +726,25 @@ pipe_poll(struct file *filp, poll_table + return mask; + } + ++static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe) ++{ ++ int kill = 0; ++ ++ spin_lock(&inode->i_lock); ++ if (!--pipe->files) { ++ inode->i_pipe = NULL; ++ kill = 1; ++ } ++ spin_unlock(&inode->i_lock); ++ ++ if (kill) ++ free_pipe_info(pipe); ++} ++ + static int + pipe_release(struct inode *inode, struct file *file) + { +- struct pipe_inode_info *pipe = inode->i_pipe; +- int kill = 0; ++ struct pipe_inode_info *pipe = file->private_data; + + __pipe_lock(pipe); + if (file->f_mode & FMODE_READ) +@@ -743,17 +757,9 @@ pipe_release(struct inode *inode, struct + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); + } +- spin_lock(&inode->i_lock); +- if (!--pipe->files) { +- inode->i_pipe = NULL; +- kill = 1; +- } +- spin_unlock(&inode->i_lock); + __pipe_unlock(pipe); + +- if (kill) +- free_pipe_info(pipe); +- ++ put_pipe_info(inode, pipe); + return 0; + } + +@@ -1014,7 +1020,6 @@ static int fifo_open(struct inode *inode + { + struct pipe_inode_info *pipe; + bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC; +- int kill = 0; + int ret; + + filp->f_version = 0; +@@ -1130,15 +1135,9 @@ err_wr: + goto err; + + err: +- spin_lock(&inode->i_lock); +- if (!--pipe->files) { +- inode->i_pipe = NULL; +- kill = 1; +- } +- spin_unlock(&inode->i_lock); + __pipe_unlock(pipe); +- if (kill) +- free_pipe_info(pipe); ++ ++ put_pipe_info(inode, pipe); + return ret; + } +