]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Dec 2013 20:02:11 +0000 (12:02 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Dec 2013 20:02:11 +0000 (12:02 -0800)
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

queue-3.10/asoc-wm8731-fix-dsp-mode-configuration.patch [new file with mode: 0644]
queue-3.10/asoc-wm8990-mark-the-register-map-as-dirty-when-powering-down.patch [new file with mode: 0644]
queue-3.10/can-c_can-don-t-call-pm_runtime_get_sync-from-interrupt-context.patch [new file with mode: 0644]
queue-3.10/can-sja1000-fix-pre-post-_irq-handling-and-irq-handler-return-value.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/vfs-fix-subtle-use-after-free-of-pipe_inode_info.patch [new file with mode: 0644]

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 (file)
index 0000000..9c21559
--- /dev/null
@@ -0,0 +1,37 @@
+From b4af6ef99a60c5b56df137d7accd81ba1ee1254e Mon Sep 17 00:00:00 2001
+From: Bo Shen <voice.shen@atmel.com>
+Date: Tue, 3 Dec 2013 18:04:54 +0800
+Subject: ASoC: wm8731: fix dsp mode configuration
+
+From: Bo Shen <voice.shen@atmel.com>
+
+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 <voice.shen@atmel.com>
+Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..67bf233
--- /dev/null
@@ -0,0 +1,30 @@
+From 2ab2b74277a86afe0dd92976db695a2bb8b93366 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 22 Nov 2013 14:17:18 +0000
+Subject: ASoC: wm8990: Mark the register map as dirty when powering down
+
+From: Mark Brown <broonie@linaro.org>
+
+commit 2ab2b74277a86afe0dd92976db695a2bb8b93366 upstream.
+
+Otherwise we'll skip sync on resume.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..20a7866
--- /dev/null
@@ -0,0 +1,74 @@
+From e35d46adc49b469fd92bdb64fea8af93640e6651 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+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 <mkl@pengutronix.de>
+
+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 <AGlen@bepmarine.com>
+Tested-by: Andrew Glen <AGlen@bepmarine.com>
+Signed-off-by: Andrew Glen <AGlen@bepmarine.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..fd23f06
--- /dev/null
@@ -0,0 +1,74 @@
+From 2fea6cd303c0d0cd9067da31d873b6a6d5bd75e7 Mon Sep 17 00:00:00 2001
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+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 <socketcan@hartkopp.net>
+
+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 <wg@grandegger.com>
+Acked-by: Wolfgang Grandegger <wg@grandegger.com>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
index e09f667c47999f3d9076d60953a45dc542918a3f..f42a4941253a261794dbbe2bb6eb362e107a8491 100644 (file)
@@ -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 (file)
index 0000000..aed9775
--- /dev/null
@@ -0,0 +1,133 @@
+From b0d8d2292160bb63de1972361ebed100c64b5b37 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 2 Dec 2013 09:44:51 -0800
+Subject: vfs: fix subtle use-after-free of pipe_inode_info
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+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 <sim@hostway.ca>
+Reported-by: Ian Applegate <ia@cloudflare.com>
+Acked-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }