[PATCH 1/4] ASoC: Intel: sof_sdw: avoid oops in error handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



While tinkering with ACPI work-arounds for the HP Omen 16 support, we
identified a corner case where the headset codec device properties are
not set in the codec .init when -EPROBE_DEFER is returned, but
released unconditionally in the .exit().

This leads to a kernel oops

[    4.186891] sof_sdw sof_sdw: snd_soc_register_card failed -517
[    4.186896] BUG: kernel NULL pointer dereference, address: 00000000000003f0
[    4.186914] Oops: 0000 [#1] PREEMPT SMP NOPTI
[    4.186926] RIP: 0010:dev_fwnode+0x5/0x20
[    4.186974]  device_remove_software_node+0x10/0x80
[    4.186982]  sof_sdw_rt711_exit+0x19/0x30 [snd_soc_sof_sdw]
[    4.186990]  mc_dailink_exit_loop+0x94/0xc0 [snd_soc_sof_sdw]
[    4.186996]  ? rt711_rtd_init+0x170/0x170 [snd_soc_sof_sdw]

A similar error case can occur if the addition of the device property
fails. We need to test if the property was successfully added before
removing it.

BugLink: https://github.com/thesofproject/linux/issues/3727
Fixes: 768ad6d80db2d ("ASoC: Intel: sof_sdw: handle errors on card registration")
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx>
Reviewed-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx>
---
 sound/soc/intel/boards/sof_sdw_rt711.c      | 3 +++
 sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c
index 49ff0871e9e7..8291967f23f3 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711.c
@@ -139,6 +139,9 @@ int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_l
 {
 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
 
+	if (!ctx->headset_codec_dev)
+		return 0;
+
 	device_remove_software_node(ctx->headset_codec_dev);
 	put_device(ctx->headset_codec_dev);
 
diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
index b3fc32bacfa8..7f16304d025b 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
@@ -140,6 +140,9 @@ int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *
 {
 	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
 
+	if (!ctx->headset_codec_dev)
+		return 0;
+
 	device_remove_software_node(ctx->headset_codec_dev);
 	put_device(ctx->headset_codec_dev);
 
-- 
2.34.1




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux