* [BUG] ALSA: hda: cs35l41: stale cs_dsp.name after component unbind breaks firmware load
@ 2026-10-29 8:46 Mads
2026-10-30 17:13 ` Stefan Binding (Opensource)
0 siblings, 1 reply; 2+ messages in thread
From: Mads @ 2026-10-29 8:46 UTC (permalink / raw)
To: David Rhodes, Richard Fitzgerald
Cc: Takashi Iwai, linux-sound@vger.kernel.org,
patches@opensource.cirrus.com
[-- Attachment #1.1: Type: text/plain, Size: 2367 bytes --]
Hi,
Same machine and kernel as my report "amp dead until reboot after one
failed system resume (shared reset)": HP Spectre x360 14-eu0xxx, SSID
103C8C15, 2x CS35L41 on I2C, kernel 7.2.5 (Omarchy distro kernel). The
code below is unchanged in mainline as of 75c1cb8178fe.
To recover the stuck right amp without a reboot, I unbound and rebound
only .1:
echo i2c-CSC3551:00-cs35l41-hda.1 > /sys/bus/i2c/drivers/cs35l41-hda/unbind
echo i2c-CSC3551:00-cs35l41-hda.1 > /sys/bus/i2c/drivers/cs35l41-hda/bind
.1 came back fine after a fresh probe. But .0, which was only unbound
and rebound as a component, could no longer load firmware:
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Falling back to default firmware.
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Unable to find firmware and tuning
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cannot Initialize Firmware. Error: -2
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cannot Run Firmware, reverting to dsp bypass...
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: CS35L41 Bound - SSID: 103C8C15, BST: 0, VSPK: 0, CH: L, FW EN: 0, SPKID: 0
The files exist, and .1 loaded the same .wmfw a moment later. Toggling
"L0 DSP1 Firmware Load" off and on gave the same -2. Only a reboot
fixed it.
From reading the code, I think it goes like this. With
firmware_autostart, the first cs35l41_hda_bind() calls
cs35l41_smart_amp() -> cs35l41_init_dsp() -> cs_dsp_halo_init(), and
cs_dsp_create_name() allocates dsp->name with
devm_kasprintf(dsp->dev, ...). Because that happens inside
component_bind(), the allocation lands in the component's devres group,
and component_unbind() releases that group. cs35l41_hda_unbind() does
not reset halo_initialized; only cs35l41_remove_dsp() does, and that
runs from remove. So the next bind skips cs_dsp_halo_init() and builds
the firmware file names from the freed dsp->name, which is a
use-after-free. The freed name also shows in .1's own messages during
its unbind ("DSP1:" becomes empty):
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: : Failed to read SCRATCH0: -16
I have not confirmed this with KASAN. Possible fixes: tear the DSP down
in cs35l41_hda_unbind() (cs35l41_remove_dsp(), or at least clear
halo_initialized and dsp->name), or keep the name allocation out of the
bind devres group.
I'm happy to test patches.
Thanks,
Mads
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 343 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
* RE: [BUG] ALSA: hda: cs35l41: stale cs_dsp.name after component unbind breaks firmware load
2026-10-29 8:46 [BUG] ALSA: hda: cs35l41: stale cs_dsp.name after component unbind breaks firmware load Mads
@ 2026-10-30 17:13 ` Stefan Binding (Opensource)
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Binding (Opensource) @ 2026-10-30 17:13 UTC (permalink / raw)
To: 'Mads', 'David Rhodes',
'Richard Fitzgerald'
Cc: 'Takashi Iwai', linux-sound, patches
Hi,
I have not been able to reproduce this on mainline kernel v7.3.
The Omarchy kernel seems to be based on, but not identical to the mainline kernel.
Are you able to reproduce this on a mainline kernel?
Thanks,
Stefan
> -----Original Message-----
> From: Mads <mhbn@proton.me>
> Sent: Thursday, October 29, 2026 8:46 AM
> To: David Rhodes <david.rhodes@cirrus.com>; Richard Fitzgerald
> <rf@opensource.cirrus.com>
> Cc: Takashi Iwai <tiwai@suse.com>; linux-sound@vger.kernel.org;
> patches@opensource.cirrus.com
> Subject: [BUG] ALSA: hda: cs35l41: stale cs_dsp.name after component
> unbind breaks firmware load
>
> Hi,
>
> Same machine and kernel as my report "amp dead until reboot after one failed
> system resume (shared reset)": HP Spectre x360 14-eu0xxx, SSID 103C8C15,
> 2x CS35L41 on I2C, kernel 7.2.5 (Omarchy distro kernel). The code below is
> unchanged in mainline as of 75c1cb8178fe.
>
> To recover the stuck right amp without a reboot, I unbound and rebound only
> .1:
>
> echo i2c-CSC3551:00-cs35l41-hda.1 > /sys/bus/i2c/drivers/cs35l41-
> hda/unbind
> echo i2c-CSC3551:00-cs35l41-hda.1 > /sys/bus/i2c/drivers/cs35l41-
> hda/bind
>
> .1 came back fine after a fresh probe. But .0, which was only unbound and
> rebound as a component, could no longer load firmware:
>
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Falling back to default
> firmware.
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Unable to find firmware and
> tuning
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cannot Initialize Firmware.
> Error: -2
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cannot Run Firmware,
> reverting to dsp bypass...
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: CS35L41 Bound - SSID:
> 103C8C15, BST: 0, VSPK: 0, CH: L, FW EN: 0, SPKID: 0
>
> The files exist, and .1 loaded the same .wmfw a moment later. Toggling
> "L0 DSP1 Firmware Load" off and on gave the same -2. Only a reboot fixed it.
>
> >From reading the code, I think it goes like this. With
> firmware_autostart, the first cs35l41_hda_bind() calls
> cs35l41_smart_amp() -> cs35l41_init_dsp() -> cs_dsp_halo_init(), and
> cs_dsp_create_name() allocates dsp->name with devm_kasprintf(dsp->dev,
> ...). Because that happens inside component_bind(), the allocation lands in
> the component's devres group, and component_unbind() releases that group.
> cs35l41_hda_unbind() does not reset halo_initialized; only
> cs35l41_remove_dsp() does, and that runs from remove. So the next bind
> skips cs_dsp_halo_init() and builds the firmware file names from the freed
> dsp->name, which is a use-after-free. The freed name also shows in .1's own
> messages during its unbind ("DSP1:" becomes empty):
>
> cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: : Failed to read SCRATCH0: -16
>
> I have not confirmed this with KASAN. Possible fixes: tear the DSP down in
> cs35l41_hda_unbind() (cs35l41_remove_dsp(), or at least clear
> halo_initialized and dsp->name), or keep the name allocation out of the bind
> devres group.
>
> I'm happy to test patches.
>
> Thanks,
> Mads
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-30 17:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-29 8:46 [BUG] ALSA: hda: cs35l41: stale cs_dsp.name after component unbind breaks firmware load Mads
2026-10-30 17:13 ` Stefan Binding (Opensource)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox