]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2016 21:20:55 +0000 (13:20 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2016 21:20:55 +0000 (13:20 -0800)
added patches:
alsa-ctl-fix-ioctls-for-x32-abi.patch
alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch
alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch
alsa-hdspm-fix-zero-division.patch
alsa-rawmidi-fix-ioctls-x32-abi.patch
alsa-seq-oss-don-t-drain-at-closing-a-client.patch
alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch
alsa-timer-fix-ioctls-for-x32-abi.patch

queue-3.14/alsa-ctl-fix-ioctls-for-x32-abi.patch [new file with mode: 0644]
queue-3.14/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch [new file with mode: 0644]
queue-3.14/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch [new file with mode: 0644]
queue-3.14/alsa-hdspm-fix-zero-division.patch [new file with mode: 0644]
queue-3.14/alsa-rawmidi-fix-ioctls-x32-abi.patch [new file with mode: 0644]
queue-3.14/alsa-seq-oss-don-t-drain-at-closing-a-client.patch [new file with mode: 0644]
queue-3.14/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch [new file with mode: 0644]
queue-3.14/alsa-timer-fix-ioctls-for-x32-abi.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/alsa-ctl-fix-ioctls-for-x32-abi.patch b/queue-3.14/alsa-ctl-fix-ioctls-for-x32-abi.patch
new file mode 100644 (file)
index 0000000..f21b4b5
--- /dev/null
@@ -0,0 +1,225 @@
+From 6236d8bb2afcfe71b88ecea554e0dc638090a45f Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Sat, 27 Feb 2016 17:52:42 +0100
+Subject: ALSA: ctl: Fix ioctls for X32 ABI
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 6236d8bb2afcfe71b88ecea554e0dc638090a45f upstream.
+
+The X32 ABI takes the same alignment like x86-64, and this may result
+in the incompatible struct size from ia32.  Unfortunately, we hit this
+in some control ABI: struct snd_ctl_elem_value differs between them
+due to the position of 64bit variable array.  This ends up with the
+unknown ioctl (ENOTTY) error.
+
+The fix is to add the compat entries for the new aligned struct.
+
+Reported-and-tested-by: Steven Newbury <steve@snewbury.org.uk>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/control_compat.c |   90 ++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 74 insertions(+), 16 deletions(-)
+
+--- a/sound/core/control_compat.c
++++ b/sound/core/control_compat.c
+@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
+         unsigned char reserved[128];
+ };
++#ifdef CONFIG_X86_X32
++/* x32 has a different alignment for 64bit values from ia32 */
++struct snd_ctl_elem_value_x32 {
++      struct snd_ctl_elem_id id;
++      unsigned int indirect;  /* bit-field causes misalignment */
++      union {
++              s32 integer[128];
++              unsigned char data[512];
++              s64 integer64[64];
++      } value;
++      unsigned char reserved[128];
++};
++#endif /* CONFIG_X86_X32 */
+ /* get the value type and count of the control */
+ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
+@@ -219,9 +232,11 @@ static int get_elem_size(int type, int c
+ static int copy_ctl_value_from_user(struct snd_card *card,
+                                   struct snd_ctl_elem_value *data,
+-                                  struct snd_ctl_elem_value32 __user *data32,
++                                  void __user *userdata,
++                                  void __user *valuep,
+                                   int *typep, int *countp)
+ {
++      struct snd_ctl_elem_value32 __user *data32 = userdata;
+       int i, type, size;
+       int uninitialized_var(count);
+       unsigned int indirect;
+@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(stru
+       if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
+           type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
+               for (i = 0; i < count; i++) {
++                      s32 __user *intp = valuep;
+                       int val;
+-                      if (get_user(val, &data32->value.integer[i]))
++                      if (get_user(val, &intp[i]))
+                               return -EFAULT;
+                       data->value.integer.value[i] = val;
+               }
+@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(stru
+                       printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
+                       return -EINVAL;
+               }
+-              if (copy_from_user(data->value.bytes.data,
+-                                 data32->value.data, size))
++              if (copy_from_user(data->value.bytes.data, valuep, size))
+                       return -EFAULT;
+       }
+@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(stru
+ }
+ /* restore the value to 32bit */
+-static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
++static int copy_ctl_value_to_user(void __user *userdata,
++                                void __user *valuep,
+                                 struct snd_ctl_elem_value *data,
+                                 int type, int count)
+ {
+@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct
+       if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
+           type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
+               for (i = 0; i < count; i++) {
++                      s32 __user *intp = valuep;
+                       int val;
+                       val = data->value.integer.value[i];
+-                      if (put_user(val, &data32->value.integer[i]))
++                      if (put_user(val, &intp[i]))
+                               return -EFAULT;
+               }
+       } else {
+               size = get_elem_size(type, count);
+-              if (copy_to_user(data32->value.data,
+-                               data->value.bytes.data, size))
++              if (copy_to_user(valuep, data->value.bytes.data, size))
+                       return -EFAULT;
+       }
+       return 0;
+ }
+-static int snd_ctl_elem_read_user_compat(struct snd_card *card, 
+-                                       struct snd_ctl_elem_value32 __user *data32)
++static int ctl_elem_read_user(struct snd_card *card,
++                            void __user *userdata, void __user *valuep)
+ {
+       struct snd_ctl_elem_value *data;
+       int err, type, count;
+@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat
+       if (data == NULL)
+               return -ENOMEM;
+-      if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
++      err = copy_ctl_value_from_user(card, data, userdata, valuep,
++                                     &type, &count);
++      if (err < 0)
+               goto error;
+       snd_power_lock(card);
+@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat
+               err = snd_ctl_elem_read(card, data);
+       snd_power_unlock(card);
+       if (err >= 0)
+-              err = copy_ctl_value_to_user(data32, data, type, count);
++              err = copy_ctl_value_to_user(userdata, valuep, data,
++                                           type, count);
+  error:
+       kfree(data);
+       return err;
+ }
+-static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
+-                                        struct snd_ctl_elem_value32 __user *data32)
++static int ctl_elem_write_user(struct snd_ctl_file *file,
++                             void __user *userdata, void __user *valuep)
+ {
+       struct snd_ctl_elem_value *data;
+       struct snd_card *card = file->card;
+@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compa
+       if (data == NULL)
+               return -ENOMEM;
+-      if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
++      err = copy_ctl_value_from_user(card, data, userdata, valuep,
++                                     &type, &count);
++      if (err < 0)
+               goto error;
+       snd_power_lock(card);
+@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compa
+               err = snd_ctl_elem_write(card, file, data);
+       snd_power_unlock(card);
+       if (err >= 0)
+-              err = copy_ctl_value_to_user(data32, data, type, count);
++              err = copy_ctl_value_to_user(userdata, valuep, data,
++                                           type, count);
+  error:
+       kfree(data);
+       return err;
+ }
++static int snd_ctl_elem_read_user_compat(struct snd_card *card,
++                                       struct snd_ctl_elem_value32 __user *data32)
++{
++      return ctl_elem_read_user(card, data32, &data32->value);
++}
++
++static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
++                                        struct snd_ctl_elem_value32 __user *data32)
++{
++      return ctl_elem_write_user(file, data32, &data32->value);
++}
++
++#ifdef CONFIG_X86_X32
++static int snd_ctl_elem_read_user_x32(struct snd_card *card,
++                                    struct snd_ctl_elem_value_x32 __user *data32)
++{
++      return ctl_elem_read_user(card, data32, &data32->value);
++}
++
++static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
++                                     struct snd_ctl_elem_value_x32 __user *data32)
++{
++      return ctl_elem_write_user(file, data32, &data32->value);
++}
++#endif /* CONFIG_X86_X32 */
++
+ /* add or replace a user control */
+ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
+                                  struct snd_ctl_elem_info32 __user *data32,
+@@ -393,6 +441,10 @@ enum {
+       SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
+       SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
+       SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
++#ifdef CONFIG_X86_X32
++      SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
++      SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
++#endif /* CONFIG_X86_X32 */
+ };
+ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(
+               return snd_ctl_elem_add_compat(ctl, argp, 0);
+       case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
+               return snd_ctl_elem_add_compat(ctl, argp, 1);
++#ifdef CONFIG_X86_X32
++      case SNDRV_CTL_IOCTL_ELEM_READ_X32:
++              return snd_ctl_elem_read_user_x32(ctl->card, argp);
++      case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
++              return snd_ctl_elem_write_user_x32(ctl, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+       down_read(&snd_ioctl_rwsem);
diff --git a/queue-3.14/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch b/queue-3.14/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch
new file mode 100644 (file)
index 0000000..eb63091
--- /dev/null
@@ -0,0 +1,39 @@
+From eab3c4db193f5fcccf70e884de9a922ca2c63d80 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 29 Feb 2016 14:26:43 +0100
+Subject: ALSA: hdsp: Fix wrong boolean ctl value accesses
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit eab3c4db193f5fcccf70e884de9a922ca2c63d80 upstream.
+
+snd-hdsp driver accesses enum item values (int) instead of boolean
+values (long) wrongly for some ctl elements.  This patch fixes them.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/rme9652/hdsp.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/rme9652/hdsp.c
++++ b/sound/pci/rme9652/hdsp.c
+@@ -2917,7 +2917,7 @@ static int snd_hdsp_get_dds_offset(struc
+ {
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+-      ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
++      ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
+       return 0;
+ }
+@@ -2929,7 +2929,7 @@ static int snd_hdsp_put_dds_offset(struc
+       if (!snd_hdsp_use_is_exclusive(hdsp))
+               return -EBUSY;
+-      val = ucontrol->value.enumerated.item[0];
++      val = ucontrol->value.integer.value[0];
+       spin_lock_irq(&hdsp->lock);
+       if (val != hdsp_dds_offset(hdsp))
+               change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
diff --git a/queue-3.14/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch b/queue-3.14/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch
new file mode 100644 (file)
index 0000000..a1b88fb
--- /dev/null
@@ -0,0 +1,50 @@
+From 537e48136295c5860a92138c5ea3959b9542868b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 29 Feb 2016 14:25:16 +0100
+Subject: ALSA: hdspm: Fix wrong boolean ctl value accesses
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 537e48136295c5860a92138c5ea3959b9542868b upstream.
+
+snd-hdspm driver accesses enum item values (int) instead of boolean
+values (long) wrongly for some ctl elements.  This patch fixes them.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/rme9652/hdspm.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/sound/pci/rme9652/hdspm.c
++++ b/sound/pci/rme9652/hdspm.c
+@@ -2270,7 +2270,7 @@ static int snd_hdspm_put_system_sample_r
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+-      hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
++      hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
+       return 0;
+ }
+@@ -4469,7 +4469,7 @@ static int snd_hdspm_get_tco_word_term(s
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+-      ucontrol->value.enumerated.item[0] = hdspm->tco->term;
++      ucontrol->value.integer.value[0] = hdspm->tco->term;
+       return 0;
+ }
+@@ -4480,8 +4480,8 @@ static int snd_hdspm_put_tco_word_term(s
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+-      if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
+-              hdspm->tco->term = ucontrol->value.enumerated.item[0];
++      if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
++              hdspm->tco->term = ucontrol->value.integer.value[0];
+               hdspm_tco_write(hdspm);
diff --git a/queue-3.14/alsa-hdspm-fix-zero-division.patch b/queue-3.14/alsa-hdspm-fix-zero-division.patch
new file mode 100644 (file)
index 0000000..ab6e4f1
--- /dev/null
@@ -0,0 +1,53 @@
+From c1099c3294c2344110085a38c50e478a5992b368 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 29 Feb 2016 14:32:42 +0100
+Subject: ALSA: hdspm: Fix zero-division
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit c1099c3294c2344110085a38c50e478a5992b368 upstream.
+
+HDSPM driver contains a code issuing zero-division potentially in
+system sample rate ctl code.  This patch fixes it by not processing
+a zero or invalid rate value as a divisor, as well as excluding the
+invalid value to be passed via the given ctl element.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/rme9652/hdspm.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/pci/rme9652/hdspm.c
++++ b/sound/pci/rme9652/hdspm.c
+@@ -1602,6 +1602,9 @@ static void hdspm_set_dds_value(struct h
+ {
+       u64 n;
++      if (snd_BUG_ON(rate <= 0))
++              return;
++
+       if (rate >= 112000)
+               rate /= 4;
+       else if (rate >= 56000)
+@@ -2224,6 +2227,8 @@ static int hdspm_get_system_sample_rate(
+               } else {
+                       /* slave mode, return external sample rate */
+                       rate = hdspm_external_sample_rate(hdspm);
++                      if (!rate)
++                              rate = hdspm->system_sample_rate;
+               }
+       }
+@@ -2269,7 +2274,10 @@ static int snd_hdspm_put_system_sample_r
+                                           ucontrol)
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
++      int rate = ucontrol->value.integer.value[0];
++      if (rate < 27000 || rate > 207000)
++              return -EINVAL;
+       hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
+       return 0;
+ }
diff --git a/queue-3.14/alsa-rawmidi-fix-ioctls-x32-abi.patch b/queue-3.14/alsa-rawmidi-fix-ioctls-x32-abi.patch
new file mode 100644 (file)
index 0000000..8434236
--- /dev/null
@@ -0,0 +1,95 @@
+From 2251fbbc1539f05b0b206b37a602d5776be37252 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Sun, 28 Feb 2016 11:28:08 +0100
+Subject: ALSA: rawmidi: Fix ioctls X32 ABI
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 2251fbbc1539f05b0b206b37a602d5776be37252 upstream.
+
+Like the previous fixes for ctl and PCM, we need a fix for
+incompatible X32 ABI regarding the rawmidi: namely, struct
+snd_rawmidi_status has the timespec, and the size and the alignment on
+X32 differ from IA32.
+
+This patch fixes the incompatible ioctl for X32.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/rawmidi_compat.c |   53 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+--- a/sound/core/rawmidi_compat.c
++++ b/sound/core/rawmidi_compat.c
+@@ -94,9 +94,58 @@ static int snd_rawmidi_ioctl_status_comp
+       return 0;
+ }
++#ifdef CONFIG_X86_X32
++/* X32 ABI has 64bit timespec and 64bit alignment */
++struct snd_rawmidi_status_x32 {
++      s32 stream;
++      u32 rsvd; /* alignment */
++      struct timespec tstamp;
++      u32 avail;
++      u32 xruns;
++      unsigned char reserved[16];
++} __attribute__((packed));
++
++#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
++
++static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
++                                      struct snd_rawmidi_status_x32 __user *src)
++{
++      int err;
++      struct snd_rawmidi_status status;
++
++      if (rfile->output == NULL)
++              return -EINVAL;
++      if (get_user(status.stream, &src->stream))
++              return -EFAULT;
++
++      switch (status.stream) {
++      case SNDRV_RAWMIDI_STREAM_OUTPUT:
++              err = snd_rawmidi_output_status(rfile->output, &status);
++              break;
++      case SNDRV_RAWMIDI_STREAM_INPUT:
++              err = snd_rawmidi_input_status(rfile->input, &status);
++              break;
++      default:
++              return -EINVAL;
++      }
++      if (err < 0)
++              return err;
++
++      if (put_timespec(&status.tstamp, &src->tstamp) ||
++          put_user(status.avail, &src->avail) ||
++          put_user(status.xruns, &src->xruns))
++              return -EFAULT;
++
++      return 0;
++}
++#endif /* CONFIG_X86_X32 */
++
+ enum {
+       SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
+       SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
++#ifdef CONFIG_X86_X32
++      SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32),
++#endif /* CONFIG_X86_X32 */
+ };
+ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+@@ -115,6 +164,10 @@ static long snd_rawmidi_ioctl_compat(str
+               return snd_rawmidi_ioctl_params_compat(rfile, argp);
+       case SNDRV_RAWMIDI_IOCTL_STATUS32:
+               return snd_rawmidi_ioctl_status_compat(rfile, argp);
++#ifdef CONFIG_X86_X32
++      case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
++              return snd_rawmidi_ioctl_status_x32(rfile, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+       return -ENOIOCTLCMD;
+ }
diff --git a/queue-3.14/alsa-seq-oss-don-t-drain-at-closing-a-client.patch b/queue-3.14/alsa-seq-oss-don-t-drain-at-closing-a-client.patch
new file mode 100644 (file)
index 0000000..87b039b
--- /dev/null
@@ -0,0 +1,82 @@
+From 197b958c1e76a575d77038cc98b4bebc2134279f Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 1 Mar 2016 18:30:18 +0100
+Subject: ALSA: seq: oss: Don't drain at closing a client
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 197b958c1e76a575d77038cc98b4bebc2134279f upstream.
+
+The OSS sequencer client tries to drain the pending events at
+releasing.  Unfortunately, as spotted by syzkaller fuzzer, this may
+lead to an unkillable process state when the event has been queued at
+the far future.  Since the process being released can't be signaled
+any longer, it remains and waits for the echo-back event in that far
+future.
+
+Back to history, the draining feature was implemented at the time we
+misinterpreted POSIX definition for blocking file operation.
+Actually, such a behavior is superfluous at release, and we should
+just release the device as is instead of keeping it up forever.
+
+This patch just removes the draining call that may block the release
+for too long time unexpectedly.
+
+BugLink: http://lkml.kernel.org/r/CACT4Y+Y4kD-aBGj37rf-xBw9bH3GMU6P+MYg4W1e-s-paVD2pg@mail.gmail.com
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/oss/seq_oss.c        |    2 --
+ sound/core/seq/oss/seq_oss_device.h |    1 -
+ sound/core/seq/oss/seq_oss_init.c   |   17 -----------------
+ 3 files changed, 20 deletions(-)
+
+--- a/sound/core/seq/oss/seq_oss.c
++++ b/sound/core/seq/oss/seq_oss.c
+@@ -150,8 +150,6 @@ odev_release(struct inode *inode, struct
+       if ((dp = file->private_data) == NULL)
+               return 0;
+-      snd_seq_oss_drain_write(dp);
+-
+       mutex_lock(&register_mutex);
+       snd_seq_oss_release(dp);
+       mutex_unlock(&register_mutex);
+--- a/sound/core/seq/oss/seq_oss_device.h
++++ b/sound/core/seq/oss/seq_oss_device.h
+@@ -131,7 +131,6 @@ int snd_seq_oss_write(struct seq_oss_dev
+ unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
+ void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
+-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
+ /* */
+ void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
+--- a/sound/core/seq/oss/seq_oss_init.c
++++ b/sound/core/seq/oss/seq_oss_init.c
+@@ -457,23 +457,6 @@ snd_seq_oss_release(struct seq_oss_devin
+ /*
+- * Wait until the queue is empty (if we don't have nonblock)
+- */
+-void
+-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
+-{
+-      if (! dp->timer->running)
+-              return;
+-      if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
+-          dp->writeq) {
+-              debug_printk(("syncing..\n"));
+-              while (snd_seq_oss_writeq_sync(dp->writeq))
+-                      ;
+-      }
+-}
+-
+-
+-/*
+  * reset sequencer devices
+  */
+ void
diff --git a/queue-3.14/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch b/queue-3.14/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch
new file mode 100644 (file)
index 0000000..8605177
--- /dev/null
@@ -0,0 +1,39 @@
+From 3a72494ac2a3bd229db941d51e7efe2f6ccd947b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Sun, 28 Feb 2016 11:36:14 +0100
+Subject: ALSA: timer: Fix broken compat timer user status ioctl
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 3a72494ac2a3bd229db941d51e7efe2f6ccd947b upstream.
+
+The timer user status compat ioctl returned the bogus struct used for
+64bit architectures instead of the 32bit one.  This patch addresses
+it to return the proper struct.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer_compat.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/core/timer_compat.c
++++ b/sound/core/timer_compat.c
+@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(
+                                       struct snd_timer_status32 __user *_status)
+ {
+       struct snd_timer_user *tu;
+-      struct snd_timer_status status;
++      struct snd_timer_status32 status;
+       
+       tu = file->private_data;
+       if (snd_BUG_ON(!tu->timeri))
+               return -ENXIO;
+       memset(&status, 0, sizeof(status));
+-      status.tstamp = tu->tstamp;
++      status.tstamp.tv_sec = tu->tstamp.tv_sec;
++      status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
+       status.resolution = snd_timer_resolution(tu->timeri);
+       status.lost = tu->timeri->lost;
+       status.overrun = tu->overrun;
diff --git a/queue-3.14/alsa-timer-fix-ioctls-for-x32-abi.patch b/queue-3.14/alsa-timer-fix-ioctls-for-x32-abi.patch
new file mode 100644 (file)
index 0000000..ea1243f
--- /dev/null
@@ -0,0 +1,59 @@
+From b24e7ad1fdc22177eb3e51584e1cfcb45d818488 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Sun, 28 Feb 2016 11:41:47 +0100
+Subject: ALSA: timer: Fix ioctls for X32 ABI
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit b24e7ad1fdc22177eb3e51584e1cfcb45d818488 upstream.
+
+X32 ABI takes the 64bit timespec, thus the timer user status ioctl becomes
+incompatible with IA32.  This results in NOTTY error when the ioctl is
+issued.
+
+Meanwhile, this struct in X32 is essentially identical with the one in
+X86-64, so we can just bypassing to the existing code for this
+specific compat ioctl.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer_compat.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/sound/core/timer_compat.c
++++ b/sound/core/timer_compat.c
+@@ -88,12 +88,21 @@ static int snd_timer_user_status_compat(
+       return 0;
+ }
++#ifdef CONFIG_X86_X32
++/* X32 ABI has the same struct as x86-64 */
++#define snd_timer_user_status_x32(file, s) \
++      snd_timer_user_status(file, s)
++#endif /* CONFIG_X86_X32 */
++
+ /*
+  */
+ enum {
+       SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
+       SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
++#ifdef CONFIG_X86_X32
++      SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status),
++#endif /* CONFIG_X86_X32 */
+ };
+ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+@@ -122,6 +131,10 @@ static long snd_timer_user_ioctl_compat(
+               return snd_timer_user_info_compat(file, argp);
+       case SNDRV_TIMER_IOCTL_STATUS32:
+               return snd_timer_user_status_compat(file, argp);
++#ifdef CONFIG_X86_X32
++      case SNDRV_TIMER_IOCTL_STATUS_X32:
++              return snd_timer_user_status_x32(file, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+       return -ENOIOCTLCMD;
+ }
index 4de146519dd64ea031637cffb19209f895efbd34..61a4601adcba6cc220a23cee7a107fcfd45cc701 100644 (file)
@@ -12,3 +12,11 @@ pm-sleep-x86-fix-crash-on-graph-trace-through-x86-suspend.patch
 revert-jffs2-fix-lock-acquisition-order-bug-in-jffs2_write_begin.patch
 jffs2-fix-page-lock-f-sem-deadlock.patch
 fix-directory-hardlinks-from-deleted-directories.patch
+alsa-ctl-fix-ioctls-for-x32-abi.patch
+alsa-rawmidi-fix-ioctls-x32-abi.patch
+alsa-timer-fix-ioctls-for-x32-abi.patch
+alsa-seq-oss-don-t-drain-at-closing-a-client.patch
+alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch
+alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch
+alsa-hdspm-fix-zero-division.patch
+alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch