[PATCH 27/30] crypto: sa2ul - change dma_alloc_pool to mempool
From: Manorit Chawdhry
Date: Tue Sep 15 2026 - 06:17:43 EST
The SA2UL engine is a DMA master, so any memory it accesses must either
be allocated coherent or be explicitly synced with the CPU cache around
each access.
The security context buffer is currently allocated from a DMA pool via
dma_pool_alloc(), which assumes a coherent memory which is untrue at a
bus level for many of our SoCs. This causes any fetch issues from SA2UL
to end up getting some stale or unsynced data causing failures for any
crypto operations.
To remove this, allocate the security context from a kmalloc-backed
mempool instead. Since this memory is now ordinary cacheable kernel
memory, explicitly call dma_map_single()/dma_unmap_single() for DMA
related operations.
Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver")
Assisted-by: Sisyphus:claude-sonnet-4-6
Signed-off-by: Manorit Chawdhry <m-chawdhry@xxxxxx>
---
drivers/crypto/sa2ul.c | 23 +++++++++++++++++------
drivers/crypto/sa2ul.h | 2 +-
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
index df905b391339..cadc8db14bbb 100644
--- a/drivers/crypto/sa2ul.c
+++ b/drivers/crypto/sa2ul.c
@@ -14,6 +14,7 @@
#include <linux/dmapool.h>
#include <linux/fips.h>
#include <linux/kernel.h>
+#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -741,6 +742,9 @@ int sa_init_sc(struct sa_ctx_info *ctx, const struct sa_match_data *match_data,
const u8 *auth_key, u16 auth_key_sz,
struct algo_data *ad, u8 enc, u32 *swinfo)
{
+ struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev);
+ struct device *dev = &data->pdev->dev;
+
int enc_sc_offset = 0;
int auth_sc_offset = 0;
u8 *sc_buf = ctx->sc;
@@ -802,6 +806,12 @@ int sa_init_sc(struct sa_ctx_info *ctx, const struct sa_match_data *match_data,
/* swizzle the security context */
sa_swiz_128(sc_buf, SA_CTX_MAX_SZ);
+ ctx->sc_phys = dma_map_single(dev, ctx->sc, SA_CTX_MAX_SZ, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, ctx->sc_phys)) {
+ mempool_free(ctx->sc, data->sc_pool);
+ return -ENOMEM;
+ }
+
sa_set_swinfo(first_engine, ctx->sc_id, ctx->sc_phys, 1, 0,
SA_SW_INFO_FLAG_EVICT, ad->hash_size, swinfo);
@@ -814,6 +824,7 @@ int sa_init_sc(struct sa_ctx_info *ctx, const struct sa_match_data *match_data,
static void sa_free_ctx_info(struct sa_ctx_info *ctx,
struct sa_crypto_data *data)
{
+ struct device *dev = &data->pdev->dev;
unsigned long bn;
bn = ctx->sc_id;
@@ -824,7 +835,8 @@ static void sa_free_ctx_info(struct sa_ctx_info *ctx,
if (ctx->sc) {
memzero_explicit(ctx->sc, SA_CTX_MAX_SZ);
- dma_pool_free(data->sc_pool, ctx->sc, ctx->sc_phys);
+ dma_unmap_single(dev, ctx->sc_phys, SA_CTX_MAX_SZ, DMA_BIDIRECTIONAL);
+ mempool_free(ctx->sc, data->sc_pool);
ctx->sc = NULL;
}
}
@@ -843,7 +855,7 @@ static int sa_init_ctx_info(struct sa_ctx_info *ctx,
ctx->sc_id = (u16)bn;
- ctx->sc = dma_pool_alloc(data->sc_pool, GFP_KERNEL, &ctx->sc_phys);
+ ctx->sc = mempool_alloc(data->sc_pool, GFP_KERNEL);
if (!ctx->sc) {
dev_err(&data->pdev->dev, "Failed to allocate SC memory\n");
err = -ENOMEM;
@@ -2244,8 +2256,7 @@ static int sa_init_mem(struct sa_crypto_data *dev_data)
{
struct device *dev = &dev_data->pdev->dev;
/* Setup dma pool for security context buffers */
- dev_data->sc_pool = dma_pool_create("keystone-sc", dev,
- SA_CTX_MAX_SZ, 64, 0);
+ dev_data->sc_pool = mempool_create_kmalloc_pool(64, SA_CTX_MAX_SZ);
if (!dev_data->sc_pool) {
dev_err(dev, "Failed to create dma pool");
return -ENOMEM;
@@ -2439,7 +2450,7 @@ static int sa_ul_probe(struct platform_device *pdev)
dma_release_channel(dev_data->dma_tx);
destroy_dma_pool:
- dma_pool_destroy(dev_data->sc_pool);
+ mempool_destroy(dev_data->sc_pool);
disable_pm:
pm_runtime_put_sync(dev);
@@ -2460,7 +2471,7 @@ static void sa_ul_remove(struct platform_device *pdev)
dma_release_channel(dev_data->dma_rx1);
dma_release_channel(dev_data->dma_tx);
- dma_pool_destroy(dev_data->sc_pool);
+ mempool_destroy(dev_data->sc_pool);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/crypto/sa2ul.h b/drivers/crypto/sa2ul.h
index fbea98981f10..7ca385e908cc 100644
--- a/drivers/crypto/sa2ul.h
+++ b/drivers/crypto/sa2ul.h
@@ -163,7 +163,7 @@ struct sa_match_data;
struct sa_crypto_data {
const struct sa_match_data *match_data;
struct platform_device *pdev;
- struct dma_pool *sc_pool;
+ mempool_t *sc_pool;
struct device *dev;
spinlock_t scid_lock; /* lock for SC-ID allocation */
/* Security context data */
--
2.43.0