Skip to content

dmaengine/net: qcom: BAM DMA XPU violation fixes for remotely-powered controllers#1400

Open
quic-vishsant wants to merge 3 commits into
qualcomm-linux:early/hwe/shikra/driversfrom
quic-vishsant:for-shikra-bam-xpu-violation-drivers
Open

dmaengine/net: qcom: BAM DMA XPU violation fixes for remotely-powered controllers#1400
quic-vishsant wants to merge 3 commits into
qualcomm-linux:early/hwe/shikra/driversfrom
quic-vishsant:for-shikra-bam-xpu-violation-drivers

Conversation

@quic-vishsant

Copy link
Copy Markdown

On Qualcomm Shikra SoC the BAM DMA controller is powered and clocked by the mDSP (VMID 43). Three related issues prevent BAM-DMUX from working on this platform:

  1. XPU violations on BAM-DMUX RX: each individually DMA-mapped RX buffer consumes one XPU Resource Group. With ~16 RGs available, 32 dma_map_single() calls exhaust the table and the first inbound transfer faults. Fixed by allocating all RX buffers as a single contiguous coherent block and SCM-assigning it once to the remote VMID at probe (net: wwan: qcom_bam_dmux).

  2. XPU violations on BAM descriptor FIFOs: the remote processor reads descriptor FIFOs as an AXI master; without an explicit SCM permission grant the first enqueue faults. Fixed by calling qcom_scm_assign_mem() once per channel allocation when qcom,vmid is set in DT (dmaengine: qcom: bam_dma).

On Qualcomm Shikra SoC the mDSP processor (VMID 43) is the AXI master
for BAM-DMUX RX transfers. Qualcomm's XPU (eXternal Protection Unit)
enforces per-region access control; each individually DMA-mapped RX
buffer requires its own XPU Resource Group (RG). With ~16 RGs available,
32 per-buffer dma_map_single() calls exhaust the RG table, causing XPU
violations on the first inbound transfer.

When qcom,vmid is present in DT, allocate all BAM_DMUX_NUM_SKB RX
buffers as a single contiguous dma_alloc_coherent() block and
SCM-assign the region to the remote VMID once at probe. This reduces
XPU RG consumption from 32 to 1. TZ does not revoke this grant on
modem crash, so a single probe-time assignment covers all restarts.

Each rx_skbs[i] slot is pre-assigned its virtual and DMA address at
probe; no per-buffer mapping is needed at power-on. Since the coherent
block is not page-backed, received payload is copied into a regular
netdev skb before handoff to the network stack.

Older platforms (MSM8916, MSM8974, MSM8939, MSM8226, QCM2290) do not
set qcom,vmid and are completely unaffected: their per-buffer
dma_map_single() path is unchanged and no coherent memory is allocated.

Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
On Qualcomm Shikra SoC the BAM DMA controller is powered and clocked by
the mDSP processor (VMID 43). The BAM hardware reads descriptor
FIFOs as an AXI master under the remote execution environment. Without
an SCM permission grant for the remote VMID, the first descriptor
enqueue triggers an XPU (eXternal Protection Unit) violation.

Add support for an optional qcom,vmid DT property on the BAM DMA
controller node. When present, bam_alloc_chan() calls
qcom_scm_assign_mem() to grant the remote VMID shared RW access to the
channel's descriptor FIFO after dma_alloc_wc(). Assignment is done
once per channel allocation. TZ does not revoke this grant on remote
processor crash, so a single allocation-time assignment is sufficient.

Platforms without qcom,vmid are unaffected: bdev->vmid is zero
(kzalloc) and the if (bdev->vmid) guard skips the SCM call entirely.

Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
…motely

When a BAM DMA controller is powered and reset by a remote processor
(powered_remotely = true), the remote side may remove BAM power during
error recovery before the driver releases DMA channels. Accessing BAM
registers after power removal causes a synchronous external abort.

Guard pipe IRQ register accesses in bam_free_chan() behind a
!powered_remotely check. The BAM SW reset (issued when the last channel
is released) retains its existing powered_remotely condition so it
continues to fire on clean driver teardown.

Similarly, skip the bam_chan_init_hw() pipe reset in
bam_dma_terminate_all() when powered_remotely, as the remote side may
have removed power by the time terminate_all is called.

Platforms that do not set powered_remotely are unaffected.

Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant