ASoC: sdw_utils: clear stale RT711 device reference on exit
Subsystems (4)
PATCH 1/1 ASoC: sdw_utils: clear stale RT711 device reference on exit
asoc_sdw_rt711_exit() drops the reference held in ctx->headset_codec_dev but leaves the pointer populated. If the card cleanup path reaches the exit hook more than once after a failed or deferred probe, a later invocation reuses the stale pointer and calls put_device() again, underflowing the refcount and leading to oopses when later probe, driver bind, or suspend paths walk the SoundWire bus after the device reference was released. Observed as boot- and suspend-time oopses on an arm64 platform with an RT712 headset codec, reproducible deterministically by repeated machine-driver probe cycling with the codec drivers unloaded.
Clear the pointer after put_device() so repeated cleanup becomes a no-op, which also makes the existing NULL check at the top of the exit hook effective. This matches what commit 046173b98de3 ("ASoC: sdw_utils:
fix double put_device() on aggregated amps") did for the aggregated amp references.
--- sound/soc/sdw_utils/soc_sdw_rt711.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/sdw_utils/soc_sdw_rt711.c +1 -0
@@ -124,6 +124,7 @@ int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_device_remove_software_node (ctx->headset_codec_dev);put_device (ctx->headset_codec_dev); + ctx->headset_codec_dev =NULL ;return 0 ; }
base-commit: 841e384b841a3d89c50b4b2d6c5bb6abab1a7e39
Signature · 1 line
2.55.0
Quoted 29 lines · David Cemin
asoc_sdw_rt711_exit()drops the reference held inctx->headset_codec_devbut leaves the pointer populated. If the card cleanup path reaches the exit hook more than once after a failed or deferred probe, a later invocation reuses the stale pointer and callsput_device()again, underflowing the refcount and leading to oopses when later probe, driver bind, or suspend paths walk the SoundWire bus after the device reference was released. Observed as boot- and suspend-time oopses on an arm64 platform with an RT712 headset codec, reproducible deterministically by repeated machine-driver probe cycling with the codec drivers unloaded.Clear the pointer after
put_device()so repeated cleanup becomes a no-op, which also makes the existing NULL check at the top of the exit hook effective. This matches what commit046173b98de3("ASoC:sdw_utils:
fix doubleput_device()on aggregated amps") did for the aggregated amp references.Fixes 811648340707 ("ASoC: Intel: sof_sdw: avoid oops in error handling")Signed-off-by David Cemin <[email protected]>--- sound/soc/sdw_utils/soc_sdw_rt711.c | 1 + 1 file changed, 1 insertion(+)sound/soc/sdw_utils/soc_sdw_rt711.c +0
-0
sound/soc/sdw_utils/soc_sdw_rt711.c int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_ · line 130
Quoted 7 lines
sound/soc/sdw_utils/soc_sdw_rt711.c +1
-0@@ -124,6 +124,7 @@ int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_device_remove_software_node (ctx->headset_codec_dev);put_device (ctx->headset_codec_dev); + ctx->headset_codec_dev =NULL ;return 0 ; }
The analysis looks correct, the only problem is that this code pattern is copy-pasted with the same issue in other files, e.g.
int asoc_sdw_es9356_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
struct asoc_sdw_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);It'd be best to use a common helper and fix this across the board, no?
Mark Brown
maintainerQuoted 1 line · David Cemin
ASoC:
sdw_utils: clear stale RT711 device reference on exit
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.4
Thanks!
[1/1] ASoC: sdw_utils: clear stale RT711 device reference on exit
https://git.kernel.org/broonie/sound/c/7c7df141dcab
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark