Patch "ALSA: pcm: Fix ioctls for X32 ABI" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Fix ioctls for X32 ABI
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
alsa-pcm-fix-ioctls-for-x32-abi.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
513ace79b657e2022a592e77f24074e088681eccMon Sep 17 00:00:00 2001
From: Takashi Iwai <[email protected]>
Date: Sun, 28 Feb 2016 11:23:09 +0100
Subject: ALSA: pcm: Fix ioctls for X32 ABI
From: Takashi Iwai <[email protected]>
commit 513ace79b657e2022a592e77f24074e088681ecc upstream.
X32 ABI uses the 64bit timespec in addition to 64bit alignment of 64bit values. This leads to incompatibilities in some PCM ioctls involved with snd_pcm_channel_info, snd_pcm_status and snd_pcm_sync_ptr structs. Fix the PCM compat ABI for these ioctls like the previous commit for ctl API.
--- sound/core/pcm_compat.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-)
sound/core/pcm_compat.c +176 -1
@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_coreturn err; } +#ifdef CONFIG_X86_X32 +/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */ +static int snd_pcm_channel_info_user (struct snd_pcm_substream *substream, +struct snd_pcm_channel_info __user *src); +#define snd_pcm_ioctl_channel_info_x32 (s, p) \ + snd_pcm_channel_info_user(s, p) +#endif /* CONFIG_X86_X32 */ +struct snd_pcm_status32 {s32 state;struct compat_timespec trigger_tstamp;
@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(streturn err; } +#ifdef CONFIG_X86_X32 +/* X32 ABI has 64bit timespec and 64bit alignment */ +struct snd_pcm_status_x32 { +s32 state; +u32 rsvd;/* alignment */ +struct timespec trigger_tstamp; +struct timespec tstamp; +u32 appl_ptr; +u32 hw_ptr; +s32 delay; +u32 avail; +u32 avail_max; +u32 overrange; +s32 suspended_state; +u32 audio_tstamp_data; +struct timespec audio_tstamp; +struct timespec driver_tstamp; +u32 audio_tstamp_accuracy; +unsigned char reserved[52 -2 *sizeof (struct timespec )]; +} __packed; + +#define put_timespec (src, dst) copy_to_user(dst, src, sizeof(*dst)) + +static int snd_pcm_status_user_x32 (struct snd_pcm_substream *substream, +struct snd_pcm_status_x32 __user *src, +bool ext) +{ +struct snd_pcm_status status; +int err; + +memset (&status,0 ,sizeof (status)); +/* +* with extension, parameters are read/write, +* get audio_tstamp_data from user, +* ignore rest of status structure +*/ +if (ext &&get_user (status.audio_tstamp_data, + (u32 __user *)(&src->audio_tstamp_data))) +return -EFAULT ; + err =snd_pcm_status (substream, &status); +if (err <0 ) +return err; + +if (clear_user (src,sizeof (*src))) +return -EFAULT ; +if (put_user (status.state, &src->state) || +put_timespec (&status.trigger_tstamp, &src->trigger_tstamp) || +put_timespec (&status.tstamp, &src->tstamp) || +put_user (status.appl_ptr, &src->appl_ptr) || +put_user (status.hw_ptr, &src->hw_ptr) || +put_user (status.delay, &src->delay) || +put_user (status.avail, &src->avail) || +put_user (status.avail_max, &src->avail_max) || +put_user (status.overrange, &src->overrange) || +put_user (status.suspended_state, &src->suspended_state) || +put_user (status.audio_tstamp_data, &src->audio_tstamp_data) || +put_timespec (&status.audio_tstamp, &src->audio_tstamp) || +put_timespec (&status.driver_tstamp, &src->driver_tstamp) || +put_user (status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy)) +return -EFAULT ; + +return err; +} +#endif /* CONFIG_X86_X32 */ +/* both for HW_PARAMS and HW_REFINE */ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, int refine,
@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compatreturn 0 ; } +#ifdef CONFIG_X86_X32 +/* X32 ABI has 64bit timespec and 64bit alignment */ +struct snd_pcm_mmap_status_x32 { +s32 state; +s32 pad1; +u32 hw_ptr; +u32 pad2;/* alignment */ +struct timespec tstamp; +s32 suspended_state; +struct timespec audio_tstamp; +} __packed; + +struct snd_pcm_mmap_control_x32 { +u32 appl_ptr; +u32 avail_min; +}; + +struct snd_pcm_sync_ptr_x32 { +u32 flags; +u32 rsvd;/* alignment */ +union { +struct snd_pcm_mmap_status_x32 status; +unsigned char reserved[64 ]; + } s; +union { +struct snd_pcm_mmap_control_x32 control; +unsigned char reserved[64 ]; + } c; +} __packed; + +static int snd_pcm_ioctl_sync_ptr_x32 (struct snd_pcm_substream *substream, +struct snd_pcm_sync_ptr_x32 __user *src) +{ +struct snd_pcm_runtime *runtime = substream->runtime; +volatile struct snd_pcm_mmap_status *status; +volatile struct snd_pcm_mmap_control *control; +u32 sflags; +struct snd_pcm_mmap_control scontrol; +struct snd_pcm_mmap_status sstatus; +snd_pcm_uframes_t boundary; +int err; + +if (snd_BUG_ON (!runtime)) +return -EINVAL ; + +if (get_user (sflags, &src->flags) || +get_user (scontrol.appl_ptr, &src->c.control.appl_ptr) || +get_user (scontrol.avail_min, &src->c.control.avail_min)) +return -EFAULT ; +if (sflags &SNDRV_PCM_SYNC_PTR_HWSYNC ) { + err =snd_pcm_hwsync (substream); +if (err <0 ) +return err; + } + status = runtime->status; + control = runtime->control; + boundary =recalculate_boundary (runtime); +if (!boundary) + boundary =0x7fffffff ; +snd_pcm_stream_lock_irq (substream); +/* FIXME: we should consider the boundary for the sync from app */ +if (!(sflags &SNDRV_PCM_SYNC_PTR_APPL )) + control->appl_ptr = scontrol.appl_ptr; +else + scontrol.appl_ptr = control->appl_ptr % boundary; +if (!(sflags &SNDRV_PCM_SYNC_PTR_AVAIL_MIN )) + control->avail_min = scontrol.avail_min; +else + scontrol.avail_min = control->avail_min; + sstatus.state = status->state; + sstatus.hw_ptr = status->hw_ptr % boundary; + sstatus.tstamp = status->tstamp; + sstatus.suspended_state = status->suspended_state; + sstatus.audio_tstamp = status->audio_tstamp; +snd_pcm_stream_unlock_irq (substream); +if (put_user (sstatus.state, &src->s.status.state) || +put_user (sstatus.hw_ptr, &src->s.status.hw_ptr) || +put_timespec (&sstatus.tstamp, &src->s.status.tstamp) || +put_user (sstatus.suspended_state, &src->s.status.suspended_state) || +put_timespec (&sstatus.audio_tstamp, &src->s.status.audio_tstamp) || +put_user (scontrol.appl_ptr, &src->c.control.appl_ptr) || +put_user (scontrol.avail_min, &src->c.control.avail_min)) +return -EFAULT ; + +return 0 ; +} +#endif /* CONFIG_X86_X32 */ /* */
@@ -487,7 +647,12 @@ enum { SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32), SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32), SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32), - +#ifdef CONFIG_X86_X32 + SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info), + SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32), + SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32), + SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32), +#endif /* CONFIG_X86_X32 */ };static long snd_pcm_ioctl_compat (struct file *file,unsigned int cmd,unsigned long arg)
@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(structreturn snd_pcm_ioctl_rewind_compat (substream, argp);case SNDRV_PCM_IOCTL_FORWARD32 :return snd_pcm_ioctl_forward_compat (substream, argp); +#ifdef CONFIG_X86_X32 +case SNDRV_PCM_IOCTL_STATUS_X32 : +return snd_pcm_status_user_x32 (substream, argp, false); +case SNDRV_PCM_IOCTL_STATUS_EXT_X32 : +return snd_pcm_status_user_x32 (substream, argp, true); +case SNDRV_PCM_IOCTL_SYNC_PTR_X32 : +return snd_pcm_ioctl_sync_ptr_x32 (substream, argp); +case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 : +return snd_pcm_ioctl_channel_info_x32 (substream, argp); +#endif /* CONFIG_X86_X32 */ }return -ENOIOCTLCMD ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/alsa-hdspm-fix-zero-division.patch queue-4.4/alsa-ctl-fix-ioctls-for-x32-abi.patch queue-4.4/alsa-hdspm-fix-wrong-boolean-ctl-value-accesses.patch queue-4.4/alsa-pcm-fix-ioctls-for-x32-abi.patch queue-4.4/alsa-hdsp-fix-wrong-boolean-ctl-value-accesses.patch queue-4.4/alsa-seq-oss-don-t-drain-at-closing-a-client.patch queue-4.4/alsa-hda-fix-mic-issues-on-acer-aspire-e1-472.patch queue-4.4/alsa-timer-fix-ioctls-for-x32-abi.patch queue-4.4/alsa-usb-audio-add-a-quirk-for-plantronics-da45.patch queue-4.4/alsa-timer-fix-broken-compat-timer-user-status-ioctl.patch queue-4.4/alsa-rawmidi-fix-ioctls-x32-abi.patch