--- /dev/null
+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);
--- /dev/null
+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;
--- /dev/null
+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);
+
--- /dev/null
+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;
+ }
--- /dev/null
+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;
+ }
--- /dev/null
+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(®ister_mutex);
+ snd_seq_oss_release(dp);
+ mutex_unlock(®ister_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
--- /dev/null
+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;
--- /dev/null
+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;
+ }
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