Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7cc3edd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "Here are lots of small fixes that have been collected since the
  previous pull.  This time, not only trivial ones but fixes for some
  serious bugs are included:

   - Fix for CPU lockups by snd-hrtimer accesses
   - Fix for unsafe disconnection handling in ALSA timer code
   - Fix for Oops due to race at HD-audio module removal
   - Fixes for possible memory corruption via 32bit PCM and sequencer
     compat ioctls
   - Fix for regression in HD-audio generic model handling
   - Suppress kernel warnings for invalid TLV ioctls that may flood up
   - Fix the missing SSC clock handling for at73c213
   - A pin fixup for ASUS N550JX"

* tag 'sound-fix-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: timer: Introduce disconnect op to snd_timer_instance
  ALSA: timer: Handle disconnection more safely
  ALSA: hda - Flush the pending probe work at remove
  ALSA: hda - Fix missing module loading with model=generic option
  ALSA: hda - Degrade i915 binding failure message
  ALSA: at73c213: manage SSC clock
  ALSA: control: Avoid kernel warnings from tlv ioctl with numid 0
  ALSA: seq: Fix snd_seq_call_port_info_ioctl in compat mode
  ALSA: pcm: Fix snd_pcm_hw_params struct copy in compat mode
  ALSA: hrtimer: Fix stall by hrtimer_cancel()
  ALSA: hda - Fix bass pin fixup for ASUS N550JX
parents 2101ae42 40ed9444
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,7 @@ struct snd_timer_instance {
			   int event,
			   int event,
			   struct timespec * tstamp,
			   struct timespec * tstamp,
			   unsigned long resolution);
			   unsigned long resolution);
	void (*disconnect)(struct snd_timer_instance *timeri);
	void *callback_data;
	void *callback_data;
	unsigned long ticks;		/* auto-load ticks when expired */
	unsigned long ticks;		/* auto-load ticks when expired */
	unsigned long cticks;		/* current ticks */
	unsigned long cticks;		/* current ticks */
+2 −0
Original line number Original line Diff line number Diff line
@@ -1405,6 +1405,8 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
		return -EFAULT;
		return -EFAULT;
	if (tlv.length < sizeof(unsigned int) * 2)
	if (tlv.length < sizeof(unsigned int) * 2)
		return -EINVAL;
		return -EINVAL;
	if (!tlv.numid)
		return -EINVAL;
	down_read(&card->controls_rwsem);
	down_read(&card->controls_rwsem);
	kctl = snd_ctl_find_numid(card, tlv.numid);
	kctl = snd_ctl_find_numid(card, tlv.numid);
	if (kctl == NULL) {
	if (kctl == NULL) {
+2 −1
Original line number Original line Diff line number Diff line
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
	struct snd_hrtimer *stime = t->private_data;
	struct snd_hrtimer *stime = t->private_data;


	atomic_set(&stime->running, 0);
	atomic_set(&stime->running, 0);
	hrtimer_cancel(&stime->hrt);
	hrtimer_try_to_cancel(&stime->hrt);
	hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
	hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
		      HRTIMER_MODE_REL);
		      HRTIMER_MODE_REL);
	atomic_set(&stime->running, 1);
	atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
{
{
	struct snd_hrtimer *stime = t->private_data;
	struct snd_hrtimer *stime = t->private_data;
	atomic_set(&stime->running, 0);
	atomic_set(&stime->running, 0);
	hrtimer_try_to_cancel(&stime->hrt);
	return 0;
	return 0;
}
}


+9 −4
Original line number Original line Diff line number Diff line
@@ -255,10 +255,15 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
	if (! (runtime = substream->runtime))
	if (! (runtime = substream->runtime))
		return -ENOTTY;
		return -ENOTTY;


	/* only fifo_size is different, so just copy all */
	data = kmalloc(sizeof(*data), GFP_KERNEL);
	data = memdup_user(data32, sizeof(*data32));
	if (!data)
	if (IS_ERR(data))
		return -ENOMEM;
		return PTR_ERR(data);

	/* only fifo_size (RO from userspace) is different, so just copy all */
	if (copy_from_user(data, data32, sizeof(*data32))) {
		err = -EFAULT;
		goto error;
	}


	if (refine)
	if (refine)
		err = snd_pcm_hw_refine(substream, data);
		err = snd_pcm_hw_refine(substream, data);
+5 −4
Original line number Original line Diff line number Diff line
@@ -49,11 +49,12 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
	struct snd_seq_port_info *data;
	struct snd_seq_port_info *data;
	mm_segment_t fs;
	mm_segment_t fs;


	data = memdup_user(data32, sizeof(*data32));
	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (IS_ERR(data))
	if (!data)
		return PTR_ERR(data);
		return -ENOMEM;


	if (get_user(data->flags, &data32->flags) ||
	if (copy_from_user(data, data32, sizeof(*data32)) ||
	    get_user(data->flags, &data32->flags) ||
	    get_user(data->time_queue, &data32->time_queue))
	    get_user(data->time_queue, &data32->time_queue))
		goto error;
		goto error;
	data->kernel = NULL;
	data->kernel = NULL;
Loading