sound fixes for 7.1
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
-----BEGIN PGP SIGNATURE-----
iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmor0GIOHHRpd2FpQHN1
c2UuZGUACgkQLtJE4w1nLE/1uQ/9GlsBaHMjMiAu/CFEVq2NWRpt1bJPoOhJoQpZ
dSfKF+RdhaxR076Kh968GNcVy/crZiHjKVCSz4Vt3qpazca2Bu3DVpyQ0gaoLu9L
G0+f14E8FVvRw5akTl83CNPQPi8vlz9fbUvUzAAReXYNwlIztZHLQoo/gSok4S5H
4PpvduVOu69E46LTvquOA0v0BTNWQ2UaMs6gaW1kRoAWupyggEbunyQKxw7riyuu
TlWvwaLh2TiEKNGsZiZRzdLFFyKpzIE8EvNgP9AauQapXX3sIqXrwVSY6wLM6+1Q
3ZCIWrgToRd9McZwW3LmOUUIIRMgq9sgjFRpzSDNFuIkYtabZpBfJOWRGVEyfVOY
pHvgYqs5kuot4Du4Kie5ObAcbz+iOyIy3TBP61M5uzC81Iy20XbNnYgwmHJAqCmZ
Wpjga6d6Tu45xQRk2RBXtutWDFKOYDQOKFvKZnLBfu5cbrsIzYkTQiR+QaAbNC92
LRgKXmMAcdIcpWFPEuRD0gNH2U6bs0oeXx6E8Rxr1wAzIzIau6JUEwPDHmR+JPFT
nAGxh4vy3aDyhyImK8DTmC7G8XmHwQyhbAYoMCrB0SvKaEKO32Ewrfa8oDXARxYQ
ooNJ90h2EO4nCJOOXzF2QZksfHQMpU27iJnHy+JUqKkp5FqskSStFKb0KXz/oYd+
3vNB6FQ=
=a42R
-----END PGP SIGNATURE-----
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
This commit is contained in:
commit
1dadb7e7eb
9 changed files with 85 additions and 15 deletions
|
|
@ -135,8 +135,9 @@ static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
|
|||
RZV2H_RSPI_TX(writel, u32)
|
||||
RZV2H_RSPI_TX(writew, u16)
|
||||
RZV2H_RSPI_TX(writeb, u8)
|
||||
/* The read access size for RSPI_SPDR is fixed at 32 bits */
|
||||
RZV2H_RSPI_RX(readl, u32)
|
||||
RZV2H_RSPI_RX(readw, u16)
|
||||
RZV2H_RSPI_RX(readl, u16)
|
||||
RZV2H_RSPI_RX(readl, u8)
|
||||
|
||||
static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
|
||||
|
|
|
|||
|
|
@ -430,6 +430,8 @@ static void snd_timer_close_locked(struct snd_timer_instance *timeri,
|
|||
|
||||
if (timer) {
|
||||
guard(spinlock_irq)(&timer->lock);
|
||||
if (timeri->flags & SNDRV_TIMER_IFLG_DEAD)
|
||||
return; /* already closed */
|
||||
timeri->flags |= SNDRV_TIMER_IFLG_DEAD;
|
||||
}
|
||||
|
||||
|
|
@ -975,18 +977,18 @@ EXPORT_SYMBOL(snd_timer_new);
|
|||
|
||||
static int snd_timer_free(struct snd_timer *timer)
|
||||
{
|
||||
struct snd_timer_instance *ti, *n;
|
||||
|
||||
if (!timer)
|
||||
return 0;
|
||||
|
||||
guard(mutex)(®ister_mutex);
|
||||
if (! list_empty(&timer->open_list_head)) {
|
||||
struct list_head *p, *n;
|
||||
struct snd_timer_instance *ti;
|
||||
pr_warn("ALSA: timer %p is busy?\n", timer);
|
||||
list_for_each_safe(p, n, &timer->open_list_head) {
|
||||
list_del_init(p);
|
||||
ti = list_entry(p, struct snd_timer_instance, open_list);
|
||||
ti->timer = NULL;
|
||||
list_for_each_entry_safe(ti, n, &timer->open_list_head, open_list) {
|
||||
struct device *card_dev_to_put = NULL;
|
||||
|
||||
snd_timer_close_locked(ti, &card_dev_to_put);
|
||||
put_device(card_dev_to_put);
|
||||
}
|
||||
}
|
||||
list_del(&timer->device_list);
|
||||
|
|
@ -1809,6 +1811,7 @@ static int snd_timer_user_params(struct file *file,
|
|||
struct snd_timer *t;
|
||||
int err;
|
||||
|
||||
guard(mutex)(®ister_mutex);
|
||||
tu = file->private_data;
|
||||
if (!tu->timeri)
|
||||
return -EBADFD;
|
||||
|
|
|
|||
|
|
@ -808,6 +808,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "MS-17LN"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PM1403CDA"),
|
||||
}
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -679,6 +679,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
|
|||
{
|
||||
struct wm_coeff_ctl *ctl = cs_ctl->priv;
|
||||
|
||||
if (!ctl)
|
||||
return;
|
||||
|
||||
cancel_work_sync(&ctl->work);
|
||||
|
||||
kfree(ctl->name);
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ loongson_pcm_pointer(struct snd_soc_component *component,
|
|||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct device *dev = substream->pcm->card->dev;
|
||||
struct loongson_runtime_data *prtd = runtime->private_data;
|
||||
struct loongson_dma_desc *desc;
|
||||
snd_pcm_uframes_t x;
|
||||
|
|
@ -207,9 +208,16 @@ loongson_pcm_pointer(struct snd_soc_component *component,
|
|||
desc = dma_desc_save(prtd);
|
||||
addr = ((u64)desc->saddr_hi << 32) | desc->saddr;
|
||||
|
||||
x = bytes_to_frames(runtime, addr - runtime->dma_addr);
|
||||
if (x == runtime->buffer_size)
|
||||
if (addr < runtime->dma_addr ||
|
||||
addr > runtime->dma_addr + runtime->dma_bytes) {
|
||||
dev_warn(dev, "WARNING! dma_addr:0x%llx\n", addr);
|
||||
x = 0;
|
||||
} else {
|
||||
x = bytes_to_frames(runtime, addr - runtime->dma_addr);
|
||||
if (x == runtime->buffer_size)
|
||||
x = 0;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ static struct sdca_dev *sdca_dev_register(struct device *parent,
|
|||
|
||||
static void sdca_dev_unregister(struct sdca_dev *sdev)
|
||||
{
|
||||
if (!sdev)
|
||||
return;
|
||||
|
||||
auxiliary_device_delete(&sdev->auxdev);
|
||||
auxiliary_device_uninit(&sdev->auxdev);
|
||||
}
|
||||
|
|
@ -90,14 +93,24 @@ int sdca_dev_register_functions(struct sdw_slave *slave)
|
|||
{
|
||||
struct sdca_device_data *sdca_data = &slave->sdca_data;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < sdca_data->num_functions; i++) {
|
||||
struct sdca_dev *func_dev;
|
||||
|
||||
func_dev = sdca_dev_register(&slave->dev,
|
||||
&sdca_data->function[i]);
|
||||
if (IS_ERR(func_dev))
|
||||
return PTR_ERR(func_dev);
|
||||
if (IS_ERR(func_dev)) {
|
||||
ret = PTR_ERR(func_dev);
|
||||
/*
|
||||
* Unregister functions that were successfully
|
||||
* registered before this failure. This also
|
||||
* sets func_dev to NULL so the caller will not
|
||||
* try to unregister them again.
|
||||
*/
|
||||
sdca_dev_unregister_functions(slave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sdca_data->function[i].func_dev = func_dev;
|
||||
}
|
||||
|
|
@ -111,7 +124,12 @@ void sdca_dev_unregister_functions(struct sdw_slave *slave)
|
|||
struct sdca_device_data *sdca_data = &slave->sdca_data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdca_data->num_functions; i++)
|
||||
for (i = 0; i < sdca_data->num_functions; i++) {
|
||||
if (!sdca_data->function[i].func_dev)
|
||||
continue;
|
||||
|
||||
sdca_dev_unregister(sdca_data->function[i].func_dev);
|
||||
sdca_data->function[i].func_dev = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA");
|
||||
|
|
|
|||
|
|
@ -181,14 +181,14 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
|
|||
}
|
||||
|
||||
dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
|
||||
if (dsp_msg) {
|
||||
if (dsp_msg == ACP_DSP_MSG_SET) {
|
||||
snd_sof_ipc_msgs_rx(sdev);
|
||||
acp_dsp_ipc_host_done(sdev);
|
||||
ipc_irq = true;
|
||||
}
|
||||
|
||||
dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
|
||||
if (dsp_ack) {
|
||||
if (dsp_ack == ACP_DSP_ACK_SET) {
|
||||
if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
|
||||
guard(spinlock_irq)(&sdev->ipc_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -377,6 +377,33 @@ void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src,
|
|||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);
|
||||
}
|
||||
|
||||
static int acp_init_scratch_mem_ipc_flags(struct snd_sof_dev *sdev)
|
||||
{
|
||||
u32 dsp_msg_write, dsp_ack_write, host_msg_write, host_ack_write;
|
||||
|
||||
dsp_msg_write = sdev->debug_box.offset +
|
||||
offsetof(struct scratch_ipc_conf, sof_dsp_msg_write);
|
||||
dsp_ack_write = sdev->debug_box.offset +
|
||||
offsetof(struct scratch_ipc_conf, sof_dsp_ack_write);
|
||||
host_msg_write = sdev->debug_box.offset +
|
||||
offsetof(struct scratch_ipc_conf, sof_host_msg_write);
|
||||
host_ack_write = sdev->debug_box.offset +
|
||||
offsetof(struct scratch_ipc_conf, sof_host_ack_write);
|
||||
/* Initialize host message write flag */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_msg_write, 0);
|
||||
|
||||
/* Initialize host ack write flag */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_ack_write, 0);
|
||||
|
||||
/* Initialize DSP message write flag */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write, 0);
|
||||
|
||||
/* Initialize DSP ack write flag */
|
||||
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acp_memory_init(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
|
||||
|
|
@ -384,6 +411,7 @@ static int acp_memory_init(struct snd_sof_dev *sdev)
|
|||
|
||||
snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, desc->dsp_intr_base + DSP_SW_INTR_CNTL_OFFSET,
|
||||
ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
|
||||
acp_init_scratch_mem_ipc_flags(sdev);
|
||||
init_dma_descriptor(adata);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@
|
|||
#define ACP_SRAM_PAGE_COUNT 128
|
||||
#define ACP6X_SDW_MAX_MANAGER_COUNT 2
|
||||
#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
|
||||
#define ACP_DSP_MSG_SET 1
|
||||
#define ACP_DSP_ACK_SET 1
|
||||
|
||||
enum clock_source {
|
||||
ACP_CLOCK_96M = 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue