[PATCH v24 00/14] crypto/dmaengine: qce: introduce BAM locking and use DMA for register I/O
Bartosz Golaszewski <[email protected]> Thu, 23 Jul 2026 19:09:06 +0200
| Newsgroups | org.kernel.vger.linux-crypto,org.infradead.lists.linux-arm-kernel,org.kernel.vger.dmaengine,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi Stephan! I took your proposed approach and modified it somewhat, thanks! Please take a look at this iteration and - as always - R-b and T-b tags will be appreciated. Merging strategy: there are build-time dependencies between the crypto and DMA patches so the best approach is for Vinod to create an immutable branch with the DMA part pulled in by the crypto tree. Currently the QCE crypto driver accesses the crypto engine registers directly via CPU. Trust Zone may perform crypto operations simultaneously resulting in a race condition. To remedy that, let's introduce support for BAM locking/unlocking to the driver. The BAM driver will now wrap any existing issued descriptor chains with additional descriptors performing the locking when the client starts the transaction (dmaengine_issue_pending()). The client wanting to profit from locking needs to switch to performing register I/O over DMA and communicate the address to which to perform the dummy writes via a call to dmaengine_desc_attach_metadata(). In the specific case of the BAM DMA this translates to sending command descriptors performing dummy writes with the relevant flags set. The BAM will then lock all other pipes not related to the current pipe group, and keep handling the current pipe only until it sees the the unlock bit. In order for the locking to work correctly, we also need to switch to using DMA for all register I/O. On top of this, the series contains some additional tweaks and refactoring. The goal of this is not to improve the performance but to prepare the driver for supporting decryption into secure buffers in the future. Tested with tcrypt.ko, kcapi and cryptsetup. Signed-off-by: Bartosz Golaszewski <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]> --- Changes in v24: - Take the approach suggested by Stephan Gerhold where we don't pre-allocate lock/unlock descriptors but write them directly into the FIFO as needed - Verify the peripheral config before setting the bchan->reconfigure flag - Reset scratchpad address if no peripheral config was passed to dmaengine_slave_config() - Verify the size of the peripheral address struct - Remove unused local variable - Link to v23: https://patch.msgid.link/[email protected] Changes in v23: - Use the same struct device that was used for mapping the scatter list to unmap it - Change the type of lock_scratchpad_addr to u32 as it's a IP-local register offset, not a physical address - Queue the work to retry the transfer if setting up pipe lock fails - Fix missing argument in dev_err() - Fix commit message wording for DMA direction - Validate DMA direction in bam_slave_config() instead of storing it and rechecking later - Link to v22: https://patch.msgid.link/[email protected] Changes in v22: - Switch back to passing the QCE scratchpad register address to the BAM DMA driver using the slave config structure but this time provide a dedicated peripheral config structure - Rename the scratchpad_addr field to lock_scratchpad_addr - Remove leftover local variables - Use the BAM struct device for DMA mapping instead of the QCE device - Use cpu_to_le32() where needed - Don't silently queue data if setting up the locks failed, defer transfer and emit an error message - Remove redundant is_lock_desc check in bam_start_dma() - Link to v21: https://patch.msgid.link/[email protected] Changes in v21: - Fix a potential race with new descriptors submitted while hardware is processing a locked sequence by clearing the bam_locked state right after queueing the UNLOCK descriptor - Link to v20: https://patch.msgid.link/[email protected] Changes in v20: - Don't use DMA cookies for LOCK/UNLOCK descriptors as this leads to dmaengine state corruption - Handle re-scheduling of a DMA transaction on full FIFO - Fix DMA descriptor leak in qce_submit_cmd_desc() - Link to v19: https://patch.msgid.link/[email protected] Changes in v19: - Fix more potential issues in remove path (sashiko) - Remove unneeded return value check for vchan_tx_prep() as it can never fail - Link to v18: https://patch.msgid.link/[email protected] Changes in v18: - Free the BAM interrupt before disabling the clock in remove() path too - convert the size assigned to command descriptors to little endian - don't pass DMA mapping attributes to dma_map_sg() in bam_dma when setting up command descriptors - Cancel the QCE workqueue *after* any outstanding DMA transfer completes - When mapping the scatterlist for command descriptors: use the actual number of mapped segments for dmaengine_prep_slave_sg() - Drop the leftover read_buf field from struct qce_device - Unmap command descriptors only after terminating the RX transfer - Pass the actual size of the metadata struct to dmaengine_desc_attach_metadata(), this is not really required for our use-case but let's do this for correctness and make sashiko happy - Drop double assignment of bam_ce_idx in qce_clear_bam_transaction() - Remove unused QCE_MAX_REG_READ - Link to v17: https://patch.msgid.link/[email protected] Changes in v17: - New patch: free the interrupt before disabling the clock in error path in probe() - New patch: cancel the QCE work on device detach - Hold the channel lock when attaching the metadata - Reorder the operations in devm_qce_dma_request() to avoid freeing memory that may still be used by the DMA channel - Register algorithms as the last step in QCE's probe() to avoid making the resources available to the system before the DMA is fully set up - Fix error paths in algo request handlers - Don't pass dmaengine attributes to map_sg_attrs() as it expects dma-mapping attribute flags - Fix a dma mapping leak for command descriptors - Rebase on top of v7.1-rc4 - Link to v16: https://patch.msgid.link/[email protected] Changes in v16: - Fix a reported race between dma_map_sg() called with spinlock taken and the corresponding dma_unmap_sg() called without it by moving the descriptor locking data into the descriptor struct - Also queue the TX data descriptors before the command descriptors to match what downstream is doing - Tweak commit messages - Rebase on top of v7.1-rc1 - Link to v15: https://patch.msgid.link/[email protected] Changes in v15: - Extend the descriptor metadata struct to also carry the channel's transfer direction and stop using dmaengine_slave_config() for that - Link to v14: https://patch.msgid.link/[email protected] Changes in v14: - Don't return an error to a client which wants to use locking on BAM that doesn't support it - Add a comment describing the DMA descriptor metadata structure - Fix memory leaks - Remove leftovers from previous iterations - Propagate errors from dma_cookie_assign() when setting up lock descriptors - Link to v13: https://patch.msgid.link/[email protected] Changes in v13: - As part of the DMA changes in the QCE driver: reverse the order of queueing the descriptors in the QCE driver: queue command descriptors with all the register writes first, followed by all the data descriptors, this is in line with the recommandations from the BAM HPG - Set the NWD (notify-when-done) bit (DMA_PREP_FENCE in dmaengine parlance) on the data descriptors to ensure that the UNLOCK descriptor will not be processed until after they have been processed by the engine. While technically the NWD bit is only needed on the final data descriptor, it's hard to tell which one *will* be the last from the driver's point-of-view and both the downstream driver as well as the Qualcomm TZ against which we want to synchronize sets NWD on every data descriptor, - Revert to creating the LOCK/UNLOCK command descriptor pair in one place now that the NWD bit is in place, - Link to v12: https://patch.msgid.link/[email protected] Changes in v12: - Wait until the transaction is done before queueing the UNLOCK command descriptor - Use descriptor metadata for communicating the scratchpad address to the BAM driver - To that end: reverse the order of the series (first BAM, then QCE) to maintain bisectability - Unmap buffers used for dummy writes after the transaction - Link to v11: https://patch.msgid.link/[email protected] Changes in v11: - Use new approach, not requiring the client to be involved in locking. - Add a patch constifying dma_descriptor_metadata_ops - Rebase on top of v7.0-rc1 - Link to v10: https://lore.kernel.org/r/[email protected] Changes in v10: - Move DESC_FLAG_(UN)LOCK BIT definitions from patch 2 to 3 - Add a patch constifying the dma engine metadata as the first in the series - Use the VERSION register for dummy lock/unlock writes - Link to v9: https://lore.kernel.org/r/[email protected] Changes in v9: - Drop the global, generic LOCK/UNLOCK flags and instead use DMA descriptor metadata ops to pass BAM-specific information from the QCE to the DMA engine - Link to v8: https://lore.kernel.org/r/[email protected] Changes in v8: - Rework the command descriptor logic and drop a lot of unneeded code - Use the physical address for BAM command descriptor access, not the mapped DMA address - Fix the problems with iommu faults on newer platforms - Generalize the LOCK/UNLOCK flags in dmaengine and reword the docs and commit messages - Make the BAM locking logic stricter in the DMA engine driver - Add some additional minor QCE driver refactoring changes to the series - Lots of small reworks and tweaks to rebase on current mainline and fix previous issues - Link to v7: https://lore.kernel.org/all/[email protected]/ Changes in v7: - remove unused code: writing to multiple registers was not used in v6, neither were the functions for reading registers over BAM DMA- - remove - don't read the SW_VERSION register needlessly in the BAM driver, instead: encode the information on whether the IP supports BAM locking in device match data - shrink code where possible with logic modifications (for instance: change the implementation of qce_write() instead of replacing it everywhere with a new symbol) - remove duplicated error messages - rework commit messages - a lot of shuffling code around for easier review and a more streamlined series - Link to v6: https://lore.kernel.org/all/[email protected]/ Changes in v6: - change "BAM" to "DMA" - Ensured this series is compilable with the current Linux-next tip of the tree (TOT). Changes in v5: - Added DMA_PREP_LOCK and DMA_PREP_UNLOCK flag support in separate patch - Removed DMA_PREP_LOCK & DMA_PREP_UNLOCK flag - Added FIELD_GET and GENMASK macro to extract major and minor version Changes in v4: - Added feature description and test hardware with test command - Fixed patch version numbering - Dropped dt-binding patch - Dropped device tree changes - Added BAM_SW_VERSION register read - Handled the error path for the api dma_map_resource() in probe - updated the commit messages for batter redability - Squash the change where qce_bam_acquire_lock() and qce_bam_release_lock() api got introduce to the change where the lock/unlock flag get introced - changed cover letter subject heading to "dmaengine: qcom: bam_dma: add cmd descriptor support" - Added the very initial post for BAM lock/unlock patch link as v1 to track this feature Changes in v3: - https://lore.kernel.org/lkml/[email protected]/ - Addressed all the comments from v2 - Added the dt-binding - Fix alignment issue - Removed type casting from qce_write_reg_dma() and qce_read_reg_dma() - Removed qce_bam_txn = dma->qce_bam_txn; line from qce_alloc_bam_txn() api and directly returning dma->qce_bam_txn Changes in v2: - https://lore.kernel.org/lkml/[email protected]/ - Initial set of patches for cmd descriptor support - Add client driver to use BAM lock/unlock feature - Added register read/write via BAM in QCE Crypto driver to use BAM lock/unlock feature --- Bartosz Golaszewski (14): dmaengine: constify struct dma_descriptor_metadata_ops dmaengine: qcom: bam_dma: free interrupt before the clock in error path dmaengine: qcom: bam_dma: convert tasklet to a BH workqueue dmaengine: qcom: bam_dma: Extend the driver's device match data dmaengine: qcom: bam_dma: Add pipe_lock_supported flag support dmaengine: qcom: bam_dma: add support for BAM locking crypto: qce - Cancel work on device detach crypto: qce - Include algapi.h in the core.h header crypto: qce - Remove unused ignore_buf crypto: qce - Simplify arguments of devm_qce_dma_request() crypto: qce - Use existing devres APIs in devm_qce_dma_request() crypto: qce - Map crypto memory for DMA crypto: qce - Add BAM DMA support for crypto register I/O crypto: qce - Communicate the base physical address to the dmaengine drivers/crypto/qce/aead.c | 10 +- drivers/crypto/qce/common.c | 20 ++-- drivers/crypto/qce/core.c | 41 ++++++- drivers/crypto/qce/core.h | 7 ++ drivers/crypto/qce/dma.c | 176 ++++++++++++++++++++++++------ drivers/crypto/qce/dma.h | 11 +- drivers/crypto/qce/sha.c | 10 +- drivers/crypto/qce/skcipher.c | 10 +- drivers/dma/qcom/bam_dma.c | 227 +++++++++++++++++++++++++++++++-------- drivers/dma/ti/k3-udma.c | 2 +- drivers/dma/xilinx/xilinx_dma.c | 2 +- include/linux/dma/qcom_bam_dma.h | 13 +++ include/linux/dmaengine.h | 2 +- 13 files changed, 420 insertions(+), 111 deletions(-) --- base-commit: bf706f42e3a457792f476fac78521b33a66aee74 change-id: 20251103-qcom-qce-cmd-descr-c5e9b11fe609 Best regards, -- Bartosz Golaszewski <[email protected]>