ASoC: Add support for AN7581 PCM driver
Subsystems (3)
v3 cover ASoC: Add support for AN7581 PCM driver
The Airoha AN7581 SoC provides a PCM interface for VoIP applications, supporting playback and capture at sample rates of 8 kHz and 16 kHz. The driver configures the PCM bit clock to 2.048 MHz and supports 8-bit and 16-bit samples, with up to 32 channels.
Add YAML and driver. This has been verified with loopback and confirmed by Airoha with ZSI voice chip.
Changes v3:
- Out of RFC
- Add Documentation patch
- Drop SLIC testing code
- Add MAINTAINERS entry
- Follow normal pattern for commit title
- Improve commit description
Changes v2:
- Rentirely rework IRQ handling
- Fix problem for timeslow configuration
- Better support duplex mode
- Better handle descriptor tracking
- Move to Soc directory
- General code fixup and cleanup
Christian Marangi (2):
ASoC: dt-bindings: airoha: Add AN7581 PCM controller
ASoC: airoha: Add support for AN7581 PCM driver
.../bindings/sound/airoha,an7581-pcm.yaml | 52 + MAINTAINERS | 7 + sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/airoha/Kconfig | 10 + sound/soc/airoha/Makefile | 3 + sound/soc/airoha/an7581-pcm.c | 910 ++++++++++++++++++ 7 files changed, 984 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/airoha,an7581-pcm.yaml create mode 100644 sound/soc/airoha/Kconfig create mode 100644 sound/soc/airoha/Makefile create mode 100644 sound/soc/airoha/an7581-pcm.c
Signature · 1 line
2.55.0
PATCH v3 1/2 ASoC: dt-bindings: airoha: Add AN7581 PCM controller
The Airoha AN7581 SoC provides a PCM interface for VoIP applications, supporting playback and capture at sample rates of 8 kHz and 16 kHz. The driver configures the PCM bit clock to 2.048 MHz and supports 8-bit and 16-bit samples, with up to 32 channels.
Document the related compatible and required interrupt/reset and provide an example for it.
--- .../bindings/sound/airoha,an7581-pcm.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/airoha,an7581-pcm.yaml
Documentation/devicetree/bindings/sound/airoha,an7581-pcm.yaml new file +52 -0
@@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/airoha,an7581-pcm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha PCM controller for AN7581 SoC + +maintainers: + - Christian Marangi <[email protected]> + +properties: + compatible: + const: airoha,an7581-pcm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + resets: + maxItems: 1 + + reset-names: + const: pcm1 + +required: + - compatible + - reg + - interrupts + - resets + - reset-names + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/reset/airoha,en7581-reset.h> + + pcm@1fbd0000 { + compatible = "airoha,an7581-pcm"; + reg = <0x1fbd0000 0x10000>; + + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + resets = <&scuclk EN7581_PCM1_RST>; + reset-names = "pcm1"; + }; + +...
Signature · 1 line
2.55.0
Re: [PATCH v3 1/2] ASoC: dt-bindings: airoha: Add AN7581 PCM controller
Quoted 5 lines · Christian Marangi
The Airoha AN7581 SoC provides a PCM interface for VoIP applications, supporting playback and capture at sample rates of 8 kHz and 16 kHz. The driver configures the PCM bit clock to 2.048 MHz and supports 8-bit and 16-bit samples, with up to 32 channels.
Quoted 9 lines
Document the related compatible and required interrupt/reset and provide an example for it.
Signed-off-by Christian Marangi <[email protected]>--- .../bindings/sound/airoha,an7581-pcm.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/airoha,an7581-pcm.yaml
PATCH v3 2/2 ASoC: airoha: Add support for AN7581 PCM driver
In reply to Christian MarangiThe Airoha AN7581 SoC provides a PCM interface for VoIP applications, supporting playback and capture at sample rates of 8 kHz and 16 kHz. The driver configures the PCM bit clock to 2.048 MHz and supports 8-bit and 16-bit samples, with up to 32 channels.
Add an ASoC platform driver for the AN7581 PCM controller configured for ZSI attached voice chip.
--- MAINTAINERS | 7 + sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/airoha/Kconfig | 10 + sound/soc/airoha/Makefile | 3 + sound/soc/airoha/an7581-pcm.c | 910 ++++++++++++++++++++++++++++++++++ 6 files changed, 932 insertions(+) create mode 100644 sound/soc/airoha/Kconfig create mode 100644 sound/soc/airoha/Makefile create mode 100644 sound/soc/airoha/an7581-pcm.c
MAINTAINERS +7 -0
@@ -776,6 +776,13 @@ F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml F: sound/soc/mediatek/an7581/* +AIROHA PCM CONTROLLER DRIVER +M: Christian Marangi <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/sound/airoha,an7581-pcm.yaml +F: sound/soc/airoha/* + AIROHA SPI SNFI DRIVER M: Lorenzo Bianconi <[email protected]> M: Ray Liu <[email protected]>
sound/soc/Kconfig +1 -0
@@ -103,6 +103,7 @@ config SND_SOC_USB # All the supported SoCs source "sound/soc/adi/Kconfig" +source "sound/soc/airoha/Kconfig" source "sound/soc/amd/Kconfig" source "sound/soc/apple/Kconfig" source "sound/soc/atmel/Kconfig"
sound/soc/Makefile +1 -0
@@ -46,6 +46,7 @@ obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ obj-$(CONFIG_SND_SOC) += apple/ obj-$(CONFIG_SND_SOC) += adi/ +obj-$(CONFIG_SND_SOC) += airoha/ obj-$(CONFIG_SND_SOC) += amd/ obj-$(CONFIG_SND_SOC) += atmel/ obj-$(CONFIG_SND_SOC) += au1x/
sound/soc/airoha/Kconfig new file +10 -0
@@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config SND_SOC_AN7581_PCM + tristate "PCM support for Airoha AN7581 chip" + depends on ARCH_AIROHA || COMPILE_TEST + help + This adds PCM driver for Airoha AN7581 boards + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N".
sound/soc/airoha/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SND_SOC_AN7581_PCM) += an7581-pcm.o
sound/soc/airoha/an7581-pcm.c new file +910 -0
910 lines not on this page · raw message
Signature · 1 line
2.55.0
[email protected]
AI reviewRe: [PATCH v3 2/2] ASoC: airoha: Add support for AN7581 PCM driver
Thank you for your contribution! Sashiko AI review found 15 potential issue(s) to consider: - [High] sound: airoha: UAF of DMA descriptors due to devm cleanup ordering - [High] sound: airoha: probe…
Thank you for your contribution! Sashiko AI review found 15 potential issue(s) to consider:
- [High] sound: airoha: UAF of DMA descriptors due to devm cleanup ordering
- [High] sound: airoha: probe fails due to IRQF_ONESHOT without thread_fn
- [High] soc: airoha: stream hangs and skips descriptors on underrun/overrun
- [High] sound: airoha: missing interrupt acknowledgement causes IRQ storm
- [High] ASoC: airoha: missing dma_set_coherent_mask() causes DMA address truncation
- [High] sound: airoha: hardware and software pointers desync after XRUN
- [High] alsa: airoha: PCM hardware is configured for non-interleaved data but advertises interleaved
- [High] sound: an7581-pcm: premature IRQ handler exit hangs stream on overrun/underrun
- [High] an7581-pcm: use-after-free of runtime in IRQ handler due to missing synchronize_irq()
- [Medium] sound: airoha: priv->users refcount leak locks hardware configuration
- [Medium] sound: airoha: unbounded tx_pos/rx_pos causes ALSA pointer discontinuity
- [Medium] sound: airoha: data race on tx_pos and tx_desc_idx in prepare()
- [Medium] sound: airoha: device_node_to_regmap() on non-syscon node leaks memory
- [Medium] sound: airoha: missing DMA memory barriers for descriptor status
- [Medium] irq: unconditional IRQ_HANDLED breaks spurious interrupt detection
--
commit 89efa182514eefdcd30c073a692953c0c449d4d3
Author: Christian Marangi <[email protected]>
Subject: ASoC: airoha: Add support for AN7581 PCM driver
This commit adds a new ALSA SoC platform driver for the Airoha AN7581 PCM controller, supporting playback and capture at sample rates of 8 kHz and 16 kHz with up to 32 channels.
sound/soc/airoha/an7581-pcm.c struct an7581_pcm_priv { · line 195
Quoted 12 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -189,11 +189,9 @@ struct an7581_pcm_priv {unsigned int rx_pos; };static const struct snd_pcm_hardware an7581_pcm_hardware = { .info =SNDRV_PCM_INFO_MMAP |SNDRV_PCM_INFO_MMAP_VALID |SNDRV_PCM_INFO_INTERLEAVED ,
[Severity: High]
Does advertising SNDRV_PCM_INFO_INTERLEAVED conflict with the hardware configuration? In hw_params, the driver sets AN7581_PCM_DESC_CHBF_OFFSET to the size of a single channel's period, matching a non-interleaved memory layout. ALSA applications will supply interleaved data, which the hardware DMA may misinterpret, outputting the wrong samples to the wrong channels.
Quoted 1 line
sound/soc/airoha/an7581-pcm.c new file +0
-0.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_U16_LE,
[ ... ]
sound/soc/airoha/an7581-pcm.c static void an7581_pcm_fe_shutdown(struct snd_pcm_substream *substream, · line 265
Quoted 8 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -259,10 +259,9 @@ static void an7581_pcm_fe_shutdown(struct snd_pcm_substream *substream,regmap_clear_bits (priv->map,AN7581_PCM_TRDCR ,AN7581_PCM_RXDMA_ENABLE ); } priv->stream[substream->stream] =NULL ;usleep_range (10000 ,20000 );
[Severity: High]
Is it possible for a delayed IRQ handler to access a freed runtime? The driver detaches the stream pointer here but does not wait for concurrent handlers to finish with synchronize_irq(). A handler executing on another CPU could have cached the substream pointer and might dereference substream->runtime after the ALSA core has freed it.
sound/soc/airoha/an7581-pcm.c static void an7581_pcm_fe_shutdown(struct snd_pcm_substream *substream,
Quoted 4 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0mutex_lock (&priv->user_lock);if (priv->users) priv->users--;
[Severity: Medium]
Is there a reference leak for priv->users if userspace calls hw_params multiple times for the same stream before it starts? Each call to hw_params increments priv->users, but shutdown only decrements it once. This can lock the stream configuration by preventing AN7581_PCM_CFG_VALID from clearing, causing subsequent hw_params calls to fail full-duplex constraints.
[ ... ]
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_fe_prepare(struct snd_pcm_substream *substream,
Quoted 13 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -274,10 +273,8 @@ static int an7581_pcm_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {struct snd_soc_pcm_runtime *rtd =snd_soc_substream_to_rtd (substream);struct an7581_pcm_priv *priv =snd_soc_card_get_drvdata (rtd->card);struct snd_pcm_runtime *runtime = substream->runtime;struct an7581_pcm_desc *desc;unsigned int period_bytes;int num_desc, i;if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) { priv->tx_pos =0 ; priv->tx_desc_idx =0 ;
[Severity: Medium]
Is there a data race when resetting tx_pos and tx_desc_idx here? These variables are modified without acquiring priv->desc_lock. Because ALSA trigger(STOP) does not call synchronize_irq(), an IRQ handler might still be executing on another CPU when prepare is called, leading to state corruption.
[Severity: High]
Could the hardware and software pointers desync after an XRUN? During stream prepare, the software index is reset to 0, but the hardware DMA base address is only written in hw_params. If prepare is called to recover from an XRUN, the hardware will resume from its previous descriptor index while the software handler expects it at index 0, potentially causing a stall.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0desc = priv->tx_descs; num_desc =AN7581_PCM_TX_DESCRIPTORS ;
[ ... ]
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_fe_prepare(struct snd_pcm_substream *substream, · line 291
Quoted 5 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -291,10 +288,8 @@ static int an7581_pcm_fe_prepare(struct snd_pcm_substream *substream, period_bytes =frames_to_bytes (runtime,AN7581_PCM_FRAMES_PER_DESC );for (i =0 ; i < num_desc; i++) { desc->status |=AN7581_PCM_DESC_STATUS_OWNERSHIP_DMA ; desc->dma_addr = runtime->dma_addr + i * period_bytes;
[Severity: High]
Will runtime->dma_addr be truncated on 64-bit systems? Since dma_set_coherent_mask() is not called in probe, coherent allocations might return a 64-bit physical address on ARM64, which would be silently truncated when assigned to the 32-bit desc->dma_addr field here.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0desc++; }
[ ... ]
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_fe_hw_params(struct snd_pcm_substream *substream, · line 455
Quoted 7 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -455,10 +450,8 @@ static int an7581_pcm_fe_hw_params(struct snd_pcm_substream *substream, }if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK )regmap_write (priv->map,AN7581_PCM_TDRBAR , priv->tx_dma);else regmap_write (priv->map,AN7581_PCM_RDRBAR , priv->rx_dma);
[Severity: High]
Could priv->tx_dma and priv->rx_dma be truncated when written? regmap_write expects an unsigned int value, which will truncate a 64-bit dma_addr_t to 32 bits on a 64-bit platform.
[ ... ]
sound/soc/airoha/an7581-pcm.c static snd_pcm_uframes_t an7581_pcm_pointer(struct snd_soc_component *component, · line 547
Quoted 10 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -546,12 +539,9 @@ static snd_pcm_uframes_t an7581_pcm_pointer(struct snd_soc_component *component,spin_lock_irqsave (&priv->desc_lock, flags);if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) pos =bytes_to_frames (runtime, priv->tx_pos);else pos =bytes_to_frames (runtime, priv->rx_pos);spin_unlock_irqrestore (&priv->desc_lock, flags);return pos % runtime->buffer_size;
[Severity: Medium]
Will this modulo operation produce a discontinuous jump when the counters overflow? tx_pos and rx_pos indefinitely increment by the period size in bytes. When the 32-bit counter wraps around UINT_MAX to 0, the modulo operation produces a jump because UINT_MAX + 1 is not typically a multiple of buffer_size. This can confuse the ALSA core and lead to an XRUN.
[ ... ]
sound/soc/airoha/an7581-pcm.c static irqreturn_t an7581_pcm_irq_handler(int irq, void *data) · line 655
Quoted 6 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -661,10 +651,8 @@ static irqreturn_t an7581_pcm_irq_handler(int irq, void *data)struct an7581_pcm_priv *priv = data;unsigned long flags;u32 status, isr =0 ;regmap_read (priv->map,AN7581_PCM_ISR , &isr);
[Severity: High]
Are pending interrupts left active here? The interrupt status is read to identify the source, but it is never explicitly written back to clear the status in AN7581_PCM_ISR. Since the DT binding specifies a level-triggered interrupt, omitting the write-back can cause a severe interrupt storm.
Quoted 3 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0/* Scan descriptor on receiving RX desc update interrupt */ if (isr &AN7581_PCM_IMR_RDESC_UPDATE_INT ) {
[ ... ]
sound/soc/airoha/an7581-pcm.c static irqreturn_t an7581_pcm_irq_handler(int irq, void *data) · line 673
Quoted 6 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -681,10 +669,8 @@ static irqreturn_t an7581_pcm_irq_handler(int irq, void *data)for (i =0 ; i <AN7581_PCM_RX_DESCRIPTORS ; i++) {spin_lock_irqsave (&priv->desc_lock, flags); desc = &priv->rx_descs[priv->rx_desc_idx]; status = desc->status;
[Severity: Medium]
Are DMA memory barriers missing here? The CPU checks descriptor ownership without a subsequent dma_rmb(), which might allow speculative reads of stale buffer data.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0if ((status &AN7581_PCM_DESC_STATUS_OWNERSHIP ) ==AN7581_PCM_DESC_STATUS_OWNERSHIP_DMA ) {
[ ... ]
sound/soc/airoha/an7581-pcm.c static irqreturn_t an7581_pcm_irq_handler(int irq, void *data) · line 694
Quoted 6 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -704,10 +690,8 @@ static irqreturn_t an7581_pcm_irq_handler(int irq, void *data)spin_unlock_irqrestore (&priv->desc_lock, flags);snd_pcm_period_elapsed (substream); desc->status |=AN7581_PCM_DESC_STATUS_OWNERSHIP_DMA ;
[Severity: Medium]
Is a dma_wmb() missing before handing ownership back to the DMA? Without it, the CPU might write the ownership status back to RAM before earlier writes are visible to the device.
sound/soc/airoha/an7581-pcm.c static irqreturn_t an7581_pcm_irq_handler(int irq, void *data) · line 696
Quoted 3 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0if (snd_pcm_capture_hw_avail (runtime) < runtime->period_size) goto handle_tx;
[Severity: High]
Does exiting early here stall the stream on underrun or overrun? If the hardware available frames drop below period_size, this early exit aborts the loop. Remaining completed descriptors are abandoned with CPU ownership, and the DMA polling demand register is not written, permanently hanging the DMA engine.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0rx_poll = true;
[ ... ]
sound/soc/airoha/an7581-pcm.c static irqreturn_t an7581_pcm_irq_handler(int irq, void *data) · line 756
Quoted 7 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -767,11 +751,9 @@ static irqreturn_t an7581_pcm_irq_handler(int irq, void *data)snd_pcm_period_elapsed (substream); desc->status |=AN7581_PCM_DESC_STATUS_OWNERSHIP_DMA ;if (snd_pcm_playback_hw_avail (runtime) < runtime->period_size)return IRQ_HANDLED ;
[Severity: Medium]
Is it safe to return IRQ_HANDLED unconditionally on early exit paths? The kernel's spurious interrupt detection mechanism relies on handlers returning IRQ_NONE when they did not service any interrupt. Blindly returning IRQ_HANDLED prevents the core from disabling a stuck interrupt line.
Quoted 3 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0tx_poll = true; }
[ ... ]
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_probe(struct platform_device *pdev) · line 774
Quoted 7 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -787,14 +769,11 @@ static int an7581_pcm_probe(struct platform_device *pdev)return -ENOMEM ;snd_soc_card_set_drvdata (card, priv); priv->map =device_node_to_regmap (dev->of_node);if (IS_ERR (priv->map))return PTR_ERR (priv->map);
[Severity: Medium]
Does calling device_node_to_regmap on a non-syscon node leak memory? This API is intended for persistent syscon devices, registering the regmap in a global static list without a cleanup function. If the driver is unloaded, the regmap structure and MMIO mapping will remain allocated forever.
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_probe(struct platform_device *pdev)
Quoted 11 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0priv->reset =devm_reset_control_get_exclusive (dev,"pcm1" );if (IS_ERR (priv->reset))return PTR_ERR (priv->reset); irq =of_irq_get (dev_of_node (dev),0 );if (irq <0 )return irq; ret =devm_request_threaded_irq (dev, irq, an7581_pcm_irq_handler,NULL ,IRQF_ONESHOT ,dev_name (dev), priv);
[Severity: High]
Will this probe fail unconditionally? devm_request_threaded_irq is called with IRQF_ONESHOT and a NULL thread_fn. According to core IRQ management, IRQF_ONESHOT requires a threaded handler, and omitting it causes request_threaded_irq to return -EINVAL and trigger a WARN_ON_ONCE.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0if (ret)return ret;
[ ... ]
sound/soc/airoha/an7581-pcm.c static int an7581_pcm_probe(struct platform_device *pdev) · line 796
Quoted 5 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -814,11 +793,8 @@ static int an7581_pcm_probe(struct platform_device *pdev)reset_control_deassert (priv->reset);usleep_range (5000 ,10000 ); ret =dma_set_mask (dev,DMA_BIT_MASK (32 ));
[Severity: High]
Should this use dma_set_mask_and_coherent instead? The streaming mask is restricted to 32 bits, but the coherent mask retains its default. On 64-bit platforms, dma_alloc_coherent might return addresses above 4GB, which are then silently truncated when assigned to the 32-bit dma_addr fields.
Quoted 2 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0if (ret)return ret;
[ ... ]
sound/soc/airoha/an7581-pcm.c static void an7581_pcm_remove(struct platform_device *pdev)
Quoted 11 lines
sound/soc/airoha/an7581-pcm.c new file +0
-0@@ -862,11 +838,8 @@ static void an7581_pcm_remove(struct platform_device *pdev) AN7581_PCM_IMR_RDESC_UPDATE_INT);regmap_clear_bits (priv->map,AN7581_PCM_TRDCR ,AN7581_PCM_TXDMA_ENABLE |AN7581_PCM_RXDMA_ENABLE );dma_free_coherent (dev,sizeof (struct an7581_pcm_desc ) *AN7581_PCM_RX_DESCRIPTORS , priv->rx_descs, priv->rx_dma);dma_free_coherent (dev,sizeof (struct an7581_pcm_desc ) *AN7581_PCM_TX_DESCRIPTORS , priv->tx_descs, priv->tx_dma); }
[Severity: High]
Does freeing the DMA descriptors explicitly here cause a use-after-free? The driver registers its ALSA components and sound card using managed devm_snd_soc_register_component and devm_snd_soc_register_card in probe. Because devres callbacks execute after remove returns, the ALSA components remain registered and accessible to user-space while and immediately after this memory is freed. A concurrent ALSA callback or an in-flight IRQ could dereference the freed descriptor arrays.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
kernel test robot
build botRe: [PATCH v3 2/2] ASoC: airoha: Add support for AN7581 PCM driver
In reply to Christian Marangikernel test robot noticed the following build warnings:
Hi Christian,
kernel test robot noticed the following build warnings:
[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on next-20261008]
[cannot apply to linus/master v7.3-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/ASoC-dt-bindings-airoha-Add-AN7581-PCM-controller/20261009-131331 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next patch link: https://lore.kernel.org/r/20261009111334.23522-3-ansuelsmth%40gmail.com patch subject: [PATCH v3 2/2] ASoC: airoha: Add support for AN7581 PCM driver config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20261010/[email protected]/config) compiler: sh4-linux-gcc (GCC) 16.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261010/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
sound/soc/airoha/an7581-pcm.c:618:10: error: 'const struct snd_soc_component_driver' has no member named 'pcm_construct'
618 | .pcm_construct = an7581_pcm_new,
| ^~~~~~~~~~~~~
sound/soc/airoha/an7581-pcm.c:618:26: error: initialization of 'int (*)(struct snd_soc_component *, struct snd_pcm_substream *, struct timespec64 *, struct timespec64 *, struct snd_pcm_audio_tstamp_config *, struct snd_pcm_audio_tstamp_report *)' from incompatible pointer type 'int (*)(struct snd_soc_component *, struct snd_soc_pcm_runtime *)' [-Wincompatible-pointer-types]
618 | .pcm_construct = an7581_pcm_new,
| ^~~~~~~~~~~~~~
sound/soc/airoha/an7581-pcm.c:618:26: note: (near initialization for 'an7581_pcm_platform.get_time_info')
sound/soc/airoha/an7581-pcm.c:603:12: note: 'an7581_pcm_new' declared here
603 | static int an7581_pcm_new(struct snd_soc_component *component,
| ^~~~~~~~~~~~~~
sound/soc/airoha/an7581-pcm.c: In function 'an7581_pcm_probe':
>> sound/soc/airoha/an7581-pcm.c:778:21: warning: unused variable 'connection_type' [-Wunused-variable]
778 | const char *connection_type;
| ^~~~~~~~~~~~~~~vim +/connection_type +778 sound/soc/airoha/an7581-pcm.c
771
772 static int an7581_pcm_probe(struct platform_device *pdev)
773 {
774 struct snd_soc_card *card = &an7581_pcm_card;
775 struct snd_soc_dai_link *dai_link;
776 struct device *dev = &pdev->dev;
777 struct an7581_pcm_priv *priv;
> 778 const char *connection_type;
779 int irq;
780 int ret;
781 int i;
782
783 card->dev = dev;
784
785 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
786 if (!priv)
787 return -ENOMEM;
788 snd_soc_card_set_drvdata(card, priv);
789
790 priv->map = device_node_to_regmap(dev->of_node);
791 if (IS_ERR(priv->map))
792 return PTR_ERR(priv->map);
793
794 priv->reset = devm_reset_control_get_exclusive(dev, "pcm1");
795 if (IS_ERR(priv->reset))
796 return PTR_ERR(priv->reset);
797
798 irq = of_irq_get(dev_of_node(dev), 0);
799 if (irq < 0)
800 return irq;
801
802 ret = devm_request_threaded_irq(dev, irq, an7581_pcm_irq_handler,
803 NULL, IRQF_ONESHOT, dev_name(dev), priv);
804 if (ret)
805 return ret;
806
807 spin_lock_init(&priv->desc_lock);
808 mutex_init(&priv->user_lock);
809
810 /* Reset the PCM interface */
811 reset_control_assert(priv->reset);
812 usleep_range(5000, 10000);
813 reset_control_deassert(priv->reset);
814 usleep_range(5000, 10000);
815
816 ret = dma_set_mask(dev, DMA_BIT_MASK(32));
817 if (ret)
818 return ret;
819
820 priv->tx_descs = dma_alloc_coherent(dev, sizeof(struct an7581_pcm_desc) *
821 AN7581_PCM_TX_DESCRIPTORS, &priv->tx_dma,
822 GFP_KERNEL);
823 if (!priv->tx_descs)
824 return -ENOMEM;
825
826 priv->rx_descs = dma_alloc_coherent(dev, sizeof(struct an7581_pcm_desc) *
827 AN7581_PCM_RX_DESCRIPTORS, &priv->rx_dma,
828 GFP_KERNEL);
829 if (!priv->rx_descs) {
830 ret = -ENOMEM;
831 goto err_free_tx;
832 }
833
834 for_each_card_prelinks(card, i, dai_link)
835 dai_link->platforms->of_node = dev->of_node;
836
837 ret = devm_snd_soc_register_component(dev,
838 &an7581_pcm_platform,
839 NULL, 0);
840 if (ret) {
841 dev_err_probe(dev, ret, "Cannot register PCM component\n");
842 goto err_free_rx;
843 }
844
845 ret = devm_snd_soc_register_component(dev,
846 &an7581_pcm_dai_component,
847 an7581_pcm_dai_driver,
848 ARRAY_SIZE(an7581_pcm_dai_driver)); 849 if (ret) {
850 dev_err_probe(dev, ret, "Cannot register PCM DAI component\n");
851 goto err_free_rx;
852 }
853
854 ret = devm_snd_soc_register_card(dev, card);
855 if (ret) {
856 dev_err_probe(dev, ret, "%s snd_soc_register_card fail\n", __func__);
857 goto err_free_rx;
858 }
859
860 return 0;
861
862 err_free_rx:
863 dma_free_coherent(dev, sizeof(struct an7581_pcm_desc) *
864 AN7581_PCM_RX_DESCRIPTORS, priv->rx_descs, priv->rx_dma);
865 err_free_tx:
866 dma_free_coherent(dev, sizeof(struct an7581_pcm_desc) *
867 AN7581_PCM_TX_DESCRIPTORS, priv->tx_descs, priv->tx_dma);
868
869 return ret;
870 }
871
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH v3 2/2] ASoC: airoha: Add support for AN7581 PCM driver
In reply to Christian Marangikernel test robot noticed the following build errors:
Hi Christian,
kernel test robot noticed the following build errors:
[auto build test ERROR on broonie-sound/for-next]
[also build test ERROR on next-20261009]
[cannot apply to linus/master v7.3-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/ASoC-dt-bindings-airoha-Add-AN7581-PCM-controller/20261009-131331 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next patch link: https://lore.kernel.org/r/20261009111334.23522-3-ansuelsmth%40gmail.com patch subject: [PATCH v3 2/2] ASoC: airoha: Add support for AN7581 PCM driver config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20261010/[email protected]/config) compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 242243a5814307de825db3428662d67b064e2cbc) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261010/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
>> sound/soc/airoha/an7581-pcm.c:618:3: error: field designator 'pcm_construct' does not refer to any field in type 'const struct snd_soc_component_driver'
618 | .pcm_construct = an7581_pcm_new,
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sound/soc/airoha/an7581-pcm.c:778:14: warning: unused variable 'connection_type' [-Wunused-variable]
778 | const char *connection_type;
| ^~~~~~~~~~~~~~~1 warning and 1 error generated.
vim +618 sound/soc/airoha/an7581-pcm.c
614
615 static const struct snd_soc_component_driver an7581_pcm_platform = {
616 .name = "an7581-pcm-audio",
617 .pointer = an7581_pcm_pointer,
> 618 .pcm_construct = an7581_pcm_new,
619 };
620
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki