Commit 9a4a6f0d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "The important fixes at this time are a couple fixes in ALSA core: a
  fix for PCM is about the OOB access in PCM OSS plugins that has been
  for long time, but hasn't hit so often until now just because we
  allocated a large buffer via vmalloc(), and surfaced more often after
  switching to kvmalloc(). Another fix is for a long-standing PCM
  problem wrt racy PM resume.

  Others are trivial nospec coverage and usual HD-audio quirks"

* tag 'sound-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops
  ALSA: pcm: Don't suspend stream in unrecoverable PCM state
  ALSA: hda/ca0132 - Simplify alt firmware loading code
  ALSA: pcm: Fix possible OOB access in PCM oss plugins
  ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256
  ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256
  ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256
  ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic
  ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286
  ALSA: seq: oss: Fix Spectre v1 vulnerability
  ALSA: rawmidi: Fix potential Spectre v1 vulnerability
parents 0e40da3e e2a829b3
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -940,6 +940,28 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
	oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
			 params_channels(params) / 8;

	err = snd_pcm_oss_period_size(substream, params, sparams);
	if (err < 0)
		goto failure;

	n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
	if (err < 0)
		goto failure;

	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
				     runtime->oss.periods, NULL);
	if (err < 0)
		goto failure;

	snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);

	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams);
	if (err < 0) {
		pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err);
		goto failure;
	}

#ifdef CONFIG_SND_PCM_OSS_PLUGINS
	snd_pcm_oss_plugin_clear(substream);
	if (!direct) {
@@ -974,27 +996,6 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
	}
#endif

	err = snd_pcm_oss_period_size(substream, params, sparams);
	if (err < 0)
		goto failure;

	n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
	if (err < 0)
		goto failure;

	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
				     runtime->oss.periods, NULL);
	if (err < 0)
		goto failure;

	snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);

	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
		pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err);
		goto failure;
	}

	if (runtime->oss.trigger) {
		sw_params->start_threshold = 1;
	} else {
+8 −1
Original line number Diff line number Diff line
@@ -1445,8 +1445,15 @@ static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
	switch (runtime->status->state) {
	case SNDRV_PCM_STATE_SUSPENDED:
		return -EBUSY;
	/* unresumable PCM state; return -EBUSY for skipping suspend */
	case SNDRV_PCM_STATE_OPEN:
	case SNDRV_PCM_STATE_SETUP:
	case SNDRV_PCM_STATE_DISCONNECTED:
		return -EBUSY;
	}
	runtime->trigger_master = substream;
	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/nospec.h>
#include <sound/rawmidi.h>
#include <sound/info.h>
#include <sound/control.h>
@@ -601,6 +602,7 @@ static int __snd_rawmidi_info_select(struct snd_card *card,
		return -ENXIO;
	if (info->stream < 0 || info->stream > 1)
		return -EINVAL;
	info->stream = array_index_nospec(info->stream, 2);
	pstr = &rmidi->streams[info->stream];
	if (pstr->substream_count == 0)
		return -ENOENT;
+4 −3
Original line number Diff line number Diff line
@@ -617,13 +617,14 @@ int
snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf)
{
	struct seq_oss_synth *rec;
	struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);

	if (dev < 0 || dev >= dp->max_synthdev)
	if (!info)
		return -ENXIO;

	if (dp->synths[dev].is_midi) {
	if (info->is_midi) {
		struct midi_info minf;
		snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf);
		snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf);
		inf->synth_type = SYNTH_TYPE_MIDI;
		inf->synth_subtype = 0;
		inf->nr_voices = 16;
+6 −14
Original line number Diff line number Diff line
@@ -1005,7 +1005,6 @@ struct ca0132_spec {
	unsigned int scp_resp_header;
	unsigned int scp_resp_data[4];
	unsigned int scp_resp_count;
	bool alt_firmware_present;
	bool startup_check_entered;
	bool dsp_reload;

@@ -7518,7 +7517,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
	bool dsp_loaded = false;
	struct ca0132_spec *spec = codec->spec;
	const struct dsp_image_seg *dsp_os_image;
	const struct firmware *fw_entry;
	const struct firmware *fw_entry = NULL;
	/*
	 * Alternate firmwares for different variants. The Recon3Di apparently
	 * can use the default firmware, but I'll leave the option in case
@@ -7529,33 +7528,26 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
	case QUIRK_R3D:
	case QUIRK_AE5:
		if (request_firmware(&fw_entry, DESKTOP_EFX_FILE,
					codec->card->dev) != 0) {
					codec->card->dev) != 0)
			codec_dbg(codec, "Desktop firmware not found.");
			spec->alt_firmware_present = false;
		} else {
		else
			codec_dbg(codec, "Desktop firmware selected.");
			spec->alt_firmware_present = true;
		}
		break;
	case QUIRK_R3DI:
		if (request_firmware(&fw_entry, R3DI_EFX_FILE,
					codec->card->dev) != 0) {
					codec->card->dev) != 0)
			codec_dbg(codec, "Recon3Di alt firmware not detected.");
			spec->alt_firmware_present = false;
		} else {
		else
			codec_dbg(codec, "Recon3Di firmware selected.");
			spec->alt_firmware_present = true;
		}
		break;
	default:
		spec->alt_firmware_present = false;
		break;
	}
	/*
	 * Use default ctefx.bin if no alt firmware is detected, or if none
	 * exists for your particular codec.
	 */
	if (!spec->alt_firmware_present) {
	if (!fw_entry) {
		codec_dbg(codec, "Default firmware selected.");
		if (request_firmware(&fw_entry, EFX_FILE,
					codec->card->dev) != 0)
Loading