History

Merge tag 'sound-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai: "A few small fixes for the last spurt. All changes are small, mostly consisting of driver-specific fixes, along with two UAF fixes for the ALSA timer core. Core: - Two UAF fixes in ALSA timer core ASoC: - SDCA: Fix NULL pointer dereference - amd / yc: Add DMI quirk for ASUS ExpertBook PM1403CDA - SOF amd: Fix garbage/spurious warnings - wm_adsp: Fix potential NULL dereference when removing firmware controls - loongson: Fix negative position calculation - spi-rzv2h-rspi: Fix SPDR read access width on 16-bit RX path" * tag 'sound-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ASoC: SDCA: fix NULL pointer dereference in sdca_dev_unregister_functions ASoC: loongson: Fix invalid position error in ls_pcm_pointer spi: rzv2h-rspi: Fix SPDR read access width for 16-bit RX ASoC: amd: yc: Add DMI quirk for ASUS EXPERTBOOK PM1403CDA ASoC: SOF: amd: set ipc flags to zero ASoC: SOF: amd: fix for ipc flags check ASoC: wm_adsp: Fix NULL dereference when removing firmware controls ALSA: timer: Fix UAF at snd_timer_user_params() ALSA: timer: Forcibly close timer instances at closing

Linus Torvalds committed 5 months ago

Commit 1dadb7e2 parents fd41dc4 b0d15539 files · +85 −15Browse files

Unified · Split

9 files
  1. drivers/spi/spi-rzv2h-rspi.c +2 −1
  2. sound/core/timer.c +10 −7
  3. sound/soc/amd/yc/acp6x-mach.c +7 −0
  4. sound/soc/codecs/wm_adsp.c +3 −0
  5. sound/soc/loongson/loongson_dma.c +10 −2
  6. sound/soc/sdca/sdca_function_device.c +21 −3
  7. sound/soc/sof/amd/acp-ipc.c +2 −2
  8. sound/soc/sof/amd/acp.c +28 −0
  9. sound/soc/sof/amd/acp.h +2 −0
drivers/spi/spi-rzv2h-rspi.c+2−1
@@ -135,8 +135,9 @@ static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \ · 134 unmodified lines
135RZV2H_RSPI_TX(writel, u32)135RZV2H_RSPI_TX(writel, u32)
136RZV2H_RSPI_TX(writew, u16)136RZV2H_RSPI_TX(writew, u16)
137RZV2H_RSPI_TX(writeb, u8)137RZV2H_RSPI_TX(writeb, u8)
138/* The read access size for RSPI_SPDR is fixed at 32 bits */
138RZV2H_RSPI_RX(readl, u32)139RZV2H_RSPI_RX(readl, u32)
139RZV2H_RSPI_RX(readw, u16)140RZV2H_RSPI_RX(readl, u16)
140RZV2H_RSPI_RX(readl, u8)141RZV2H_RSPI_RX(readl, u8)
141 142
142static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,143static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
sound/core/timer.c+10−7
@@ -430,6 +430,8 @@ static void snd_timer_close_locked(struct snd_timer_instance *timeri, · 429 unmodified lines
430 430
431 if (timer) {431 if (timer) {
432 guard(spinlock_irq)(&timer->lock);432 guard(spinlock_irq)(&timer->lock);
433 if (timeri->flags & SNDRV_TIMER_IFLG_DEAD)
434 return; /* already closed */
433 timeri->flags |= SNDRV_TIMER_IFLG_DEAD;435 timeri->flags |= SNDRV_TIMER_IFLG_DEAD;
434 }436 }
435 437
@@ -975,18 +977,18 @@ EXPORT_SYMBOL(snd_timer_new); · 539 unmodified lines
975 977
976static int snd_timer_free(struct snd_timer *timer)978static int snd_timer_free(struct snd_timer *timer)
977{979{
980 struct snd_timer_instance *ti, *n;
981
978 if (!timer)982 if (!timer)
979 return 0;983 return 0;
980 984
981 guard(mutex)(&register_mutex);985 guard(mutex)(&register_mutex);
982 if (! list_empty(&timer->open_list_head)) {986 if (! list_empty(&timer->open_list_head)) {
983 struct list_head *p, *n;987 list_for_each_entry_safe(ti, n, &timer->open_list_head, open_list) {
984 struct snd_timer_instance *ti;988 struct device *card_dev_to_put = NULL;
985 pr_warn("ALSA: timer %p is busy?\n", timer);989
986 list_for_each_safe(p, n, &timer->open_list_head) {990 snd_timer_close_locked(ti, &card_dev_to_put);
987 list_del_init(p);991 put_device(card_dev_to_put);
988 ti = list_entry(p, struct snd_timer_instance, open_list);
989 ti->timer = NULL;
990 }992 }
991 }993 }
992 list_del(&timer->device_list);994 list_del(&timer->device_list);
@@ -1809,6 +1811,7 @@ static int snd_timer_user_params(struct file *file, · 816 unmodified lines
1809 struct snd_timer *t;1811 struct snd_timer *t;
1810 int err;1812 int err;
1811 1813
1814 guard(mutex)(&register_mutex);
1812 tu = file->private_data;1815 tu = file->private_data;
1813 if (!tu->timeri)1816 if (!tu->timeri)
1814 return -EBADFD;1817 return -EBADFD;
sound/soc/amd/yc/acp6x-mach.c+7−0
@@ -808,6 +808,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 807 unmodified lines
808 DMI_MATCH(DMI_BOARD_NAME, "MS-17LN"),808 DMI_MATCH(DMI_BOARD_NAME, "MS-17LN"),
809 }809 }
810 },810 },
811 {
812 .driver_data = &acp6x_card,
813 .matches = {
814 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
815 DMI_MATCH(DMI_BOARD_NAME, "PM1403CDA"),
816 }
817 },
811 {}818 {}
812};819};
813 820
sound/soc/codecs/wm_adsp.c+3−0
@@ -679,6 +679,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) · 678 unmodified lines
679{679{
680 struct wm_coeff_ctl *ctl = cs_ctl->priv;680 struct wm_coeff_ctl *ctl = cs_ctl->priv;
681 681
682 if (!ctl)
683 return;
684
682 cancel_work_sync(&ctl->work);685 cancel_work_sync(&ctl->work);
683 686
684 kfree(ctl->name);687 kfree(ctl->name);
sound/soc/loongson/loongson_dma.c+10−2
@@ -199,6 +199,7 @@ loongson_pcm_pointer(struct snd_soc_component *component, · 198 unmodified lines
199 struct snd_pcm_substream *substream)199 struct snd_pcm_substream *substream)
200{200{
201 struct snd_pcm_runtime *runtime = substream->runtime;201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct device *dev = substream->pcm->card->dev;
202 struct loongson_runtime_data *prtd = runtime->private_data;203 struct loongson_runtime_data *prtd = runtime->private_data;
203 struct loongson_dma_desc *desc;204 struct loongson_dma_desc *desc;
204 snd_pcm_uframes_t x;205 snd_pcm_uframes_t x;
@@ -207,9 +208,16 @@ loongson_pcm_pointer(struct snd_soc_component *component, · 2 unmodified lines
207 desc = dma_desc_save(prtd);208 desc = dma_desc_save(prtd);
208 addr = ((u64)desc->saddr_hi << 32) | desc->saddr;209 addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
209 210
210 x = bytes_to_frames(runtime, addr - runtime->dma_addr);211 if (addr < runtime->dma_addr ||
211 if (x == runtime->buffer_size)212 addr > runtime->dma_addr + runtime->dma_bytes) {
213 dev_warn(dev, "WARNING! dma_addr:0x%llx\n", addr);
212 x = 0;214 x = 0;
215 } else {
216 x = bytes_to_frames(runtime, addr - runtime->dma_addr);
217 if (x == runtime->buffer_size)
218 x = 0;
219 }
220
213 return x;221 return x;
214}222}
215 223
sound/soc/sdca/sdca_function_device.c+21−3
@@ -82,6 +82,9 @@ static struct sdca_dev *sdca_dev_register(struct device *parent, · 81 unmodified lines
82 82
83static void sdca_dev_unregister(struct sdca_dev *sdev)83static void sdca_dev_unregister(struct sdca_dev *sdev)
84{84{
85 if (!sdev)
86 return;
87
85 auxiliary_device_delete(&sdev->auxdev);88 auxiliary_device_delete(&sdev->auxdev);
86 auxiliary_device_uninit(&sdev->auxdev);89 auxiliary_device_uninit(&sdev->auxdev);
87}90}
@@ -90,14 +93,24 @@ int sdca_dev_register_functions(struct sdw_slave *slave) · 2 unmodified lines
90{93{
91 struct sdca_device_data *sdca_data = &slave->sdca_data;94 struct sdca_device_data *sdca_data = &slave->sdca_data;
92 int i;95 int i;
96 int ret;
93 97
94 for (i = 0; i < sdca_data->num_functions; i++) {98 for (i = 0; i < sdca_data->num_functions; i++) {
95 struct sdca_dev *func_dev;99 struct sdca_dev *func_dev;
96 100
97 func_dev = sdca_dev_register(&slave->dev,101 func_dev = sdca_dev_register(&slave->dev,
98 &sdca_data->function[i]);102 &sdca_data->function[i]);
99 if (IS_ERR(func_dev))103 if (IS_ERR(func_dev)) {
100 return PTR_ERR(func_dev);104 ret = PTR_ERR(func_dev);
105 /*
106 * Unregister functions that were successfully
107 * registered before this failure. This also
108 * sets func_dev to NULL so the caller will not
109 * try to unregister them again.
110 */
111 sdca_dev_unregister_functions(slave);
112 return ret;
113 }
101 114
102 sdca_data->function[i].func_dev = func_dev;115 sdca_data->function[i].func_dev = func_dev;
103 }116 }
@@ -111,7 +124,12 @@ void sdca_dev_unregister_functions(struct sdw_slave *slave) · 7 unmodified lines
111 struct sdca_device_data *sdca_data = &slave->sdca_data;124 struct sdca_device_data *sdca_data = &slave->sdca_data;
112 int i;125 int i;
113 126
114 for (i = 0; i < sdca_data->num_functions; i++)127 for (i = 0; i < sdca_data->num_functions; i++) {
128 if (!sdca_data->function[i].func_dev)
129 continue;
130
115 sdca_dev_unregister(sdca_data->function[i].func_dev);131 sdca_dev_unregister(sdca_data->function[i].func_dev);
132 sdca_data->function[i].func_dev = NULL;
133 }
116}134}
117EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA");135EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA");
sound/soc/sof/amd/acp-ipc.c+2−2
@@ -181,14 +181,14 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context) · 180 unmodified lines
181 }181 }
182 182
183 dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);183 dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
184 if (dsp_msg) {184 if (dsp_msg == ACP_DSP_MSG_SET) {
185 snd_sof_ipc_msgs_rx(sdev);185 snd_sof_ipc_msgs_rx(sdev);
186 acp_dsp_ipc_host_done(sdev);186 acp_dsp_ipc_host_done(sdev);
187 ipc_irq = true;187 ipc_irq = true;
188 }188 }
189 189
190 dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);190 dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
191 if (dsp_ack) {191 if (dsp_ack == ACP_DSP_ACK_SET) {
192 if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {192 if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
193 guard(spinlock_irq)(&sdev->ipc_lock);193 guard(spinlock_irq)(&sdev->ipc_lock);
194 194
sound/soc/sof/amd/acp.c+28−0
@@ -377,6 +377,33 @@ void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, · 376 unmodified lines
377 snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);377 snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);
378}378}
379 379
380static int acp_init_scratch_mem_ipc_flags(struct snd_sof_dev *sdev)
381{
382 u32 dsp_msg_write, dsp_ack_write, host_msg_write, host_ack_write;
383
384 dsp_msg_write = sdev->debug_box.offset +
385 offsetof(struct scratch_ipc_conf, sof_dsp_msg_write);
386 dsp_ack_write = sdev->debug_box.offset +
387 offsetof(struct scratch_ipc_conf, sof_dsp_ack_write);
388 host_msg_write = sdev->debug_box.offset +
389 offsetof(struct scratch_ipc_conf, sof_host_msg_write);
390 host_ack_write = sdev->debug_box.offset +
391 offsetof(struct scratch_ipc_conf, sof_host_ack_write);
392 /* Initialize host message write flag */
393 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_msg_write, 0);
394
395 /* Initialize host ack write flag */
396 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_ack_write, 0);
397
398 /* Initialize DSP message write flag */
399 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write, 0);
400
401 /* Initialize DSP ack write flag */
402 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write, 0);
403
404 return 0;
405}
406
380static int acp_memory_init(struct snd_sof_dev *sdev)407static int acp_memory_init(struct snd_sof_dev *sdev)
381{408{
382 struct acp_dev_data *adata = sdev->pdata->hw_pdata;409 struct acp_dev_data *adata = sdev->pdata->hw_pdata;
@@ -384,6 +411,7 @@ static int acp_memory_init(struct snd_sof_dev *sdev) · 1 unmodified line
384 411
385 snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_CNTL_OFFSET,412 snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_CNTL_OFFSET,
386 ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);413 ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
414 acp_init_scratch_mem_ipc_flags(sdev);
387 init_dma_descriptor(adata);415 init_dma_descriptor(adata);
388 416
389 return 0;417 return 0;
sound/soc/sof/amd/acp.h+2−0
@@ -116,6 +116,8 @@ · 115 unmodified lines
116#define ACP_SRAM_PAGE_COUNT 128116#define ACP_SRAM_PAGE_COUNT 128
117#define ACP6X_SDW_MAX_MANAGER_COUNT 2117#define ACP6X_SDW_MAX_MANAGER_COUNT 2
118#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT118#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
119#define ACP_DSP_MSG_SET 1
120#define ACP_DSP_ACK_SET 1
119 121
120enum clock_source {122enum clock_source {
121 ACP_CLOCK_96M = 0,123 ACP_CLOCK_96M = 0,