mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
adsp: Fix crash in fe_widget_event after pcm close
Dangling reference to pcm runtime data in app->private_data was leading to a kernel crash. Assigning null in pcm close callback and validating appropriately in fe_widget_event() solves the problem. Bug 2402965 Change-Id: I72b9008fde83ac55d032670b9ecd95560ef89e3a Signed-off-by: Niranjan Dighe <ndighe@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1979759 (cherry picked from commit d03c2843e9376d0e674236b40bf516b91f808820) Reviewed-on: https://git-master.nvidia.com/r/2126291 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Hariharan Sivaraman <hariharans@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Uday Gupta <udayg@nvidia.com> Reviewed-by: Dipesh Gandhi <dipeshg@nvidia.com> Reviewed-by: Nitin Pai <npai@nvidia.com> Tested-by: Nitin Pai <npai@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
281827694d
commit
f0c6c418c5
@@ -1821,6 +1821,8 @@ static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream)
|
|||||||
prtd->fe_apm->msg_handler =
|
prtd->fe_apm->msg_handler =
|
||||||
tegra210_adsp_app_default_msg_handler;
|
tegra210_adsp_app_default_msg_handler;
|
||||||
|
|
||||||
|
prtd->fe_apm->private_data = NULL;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&prtd->fe_apm->lock, flags);
|
spin_unlock_irqrestore(&prtd->fe_apm->lock, flags);
|
||||||
|
|
||||||
prtd->fe_apm->fe = 1;
|
prtd->fe_apm->fe = 1;
|
||||||
@@ -2689,10 +2691,10 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (event == SND_SOC_DAPM_POST_PMD) {
|
} else if (event == SND_SOC_DAPM_POST_PMD) {
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
dev_info(adsp->dev, "disconnect event on APM %d, ADSP-FE %d\n",
|
dev_info(adsp->dev, "disconnect event on APM %d, ADSP-FE %d\n",
|
||||||
(i + 1) - APM_IN_START, w->reg);
|
(i + 1) - APM_IN_START, w->reg);
|
||||||
prtd = apm->private_data;
|
|
||||||
runtime = prtd->substream->runtime;
|
|
||||||
|
|
||||||
ret = tegra210_adsp_send_state_msg(apm, nvfx_state_inactive,
|
ret = tegra210_adsp_send_state_msg(apm, nvfx_state_inactive,
|
||||||
TEGRA210_ADSP_MSG_FLAG_SEND | TEGRA210_ADSP_MSG_FLAG_NEED_ACK);
|
TEGRA210_ADSP_MSG_FLAG_SEND | TEGRA210_ADSP_MSG_FLAG_NEED_ACK);
|
||||||
@@ -2701,6 +2703,16 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w,
|
|||||||
goto err_put;
|
goto err_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&apm->lock, flags);
|
||||||
|
prtd = apm->private_data;
|
||||||
|
|
||||||
|
if (!prtd) {
|
||||||
|
dev_dbg(adsp->dev, "PCM close caused this widget event\n");
|
||||||
|
spin_unlock_irqrestore(&apm->lock, flags);
|
||||||
|
goto err_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime = prtd->substream->runtime;
|
||||||
runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||||
if (!(prtd->substream->f_flags & O_NONBLOCK)) {
|
if (!(prtd->substream->f_flags & O_NONBLOCK)) {
|
||||||
if (IS_MMAP_ACCESS(runtime->access))
|
if (IS_MMAP_ACCESS(runtime->access))
|
||||||
@@ -2708,6 +2720,9 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w,
|
|||||||
else
|
else
|
||||||
wake_up(&runtime->tsleep);
|
wake_up(&runtime->tsleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&apm->lock, flags);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pr_err("%s: error. unknown event: %d\n", __func__, event);
|
pr_err("%s: error. unknown event: %d\n", __func__, event);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user