* [PATCH v3 04/11] crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Previously added code to talitos_submit() in order to map an entire
descriptor chain.
Move that code into a standalone function to improve readability.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 75 ++++++++++++++++++++++++++----------------------
1 file changed, 41 insertions(+), 34 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a98b40f566dd..183d51fa9a4a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -255,6 +255,46 @@ static int init_device(struct device *dev)
return 0;
}
+static void dma_map_request(struct device *dev, struct talitos_request *request,
+ struct talitos_desc *desc, bool is_sec1)
+{
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
+ dma_addr_t dma_desc, prev_dma_desc;
+ struct talitos_edesc *prev_edesc = NULL;
+
+ if (is_sec1) {
+ while (edesc) {
+ edesc->desc.hdr1 = edesc->desc.hdr;
+
+ dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
+ TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ if (!prev_edesc) {
+ request->dma_desc = dma_desc;
+ goto next;
+ }
+
+ /* Chain in any previous descriptors. */
+
+ prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
+
+ dma_sync_single_for_device(dev, prev_dma_desc,
+ TALITOS_DESC_SIZE,
+ DMA_TO_DEVICE);
+
+next:
+ prev_edesc = edesc;
+ prev_dma_desc = dma_desc;
+ edesc = edesc->next_desc;
+ }
+ } else {
+ request->dma_desc = dma_map_single(dev, desc, TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
+}
+
/**
* talitos_submit - submits a descriptor to the device for processing
* @dev: the SEC device to be used
@@ -273,10 +313,7 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
void *context, int error),
void *context)
{
- struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
struct talitos_private *priv = dev_get_drvdata(dev);
- dma_addr_t dma_desc, prev_dma_desc;
- struct talitos_edesc *prev_edesc = NULL;
struct talitos_request *request;
unsigned long flags;
int head;
@@ -294,37 +331,7 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
request = &priv->chan[ch].fifo[head];
/* map descriptor and save caller data */
- if (is_sec1) {
- while (edesc) {
- edesc->desc.hdr1 = edesc->desc.hdr;
-
- dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
-
- if (!prev_edesc) {
- request->dma_desc = dma_desc;
- goto next;
- }
-
- /* Chain in any previous descriptors. */
-
- prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
-
- dma_sync_single_for_device(dev, prev_dma_desc,
- TALITOS_DESC_SIZE,
- DMA_TO_DEVICE);
-
-next:
- prev_edesc = edesc;
- prev_dma_desc = dma_desc;
- edesc = edesc->next_desc;
- }
- } else {
- request->dma_desc = dma_map_single(dev, desc,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
- }
+ dma_map_request(dev, request, desc, is_sec1);
request->callback = callback;
request->context = context;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 03/11] crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Previously added code to flush_channel() in order to unmap an entire
descriptor.
Move that code into a standalone function to improve readability.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b0ebf99b94f5..a98b40f566dd 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -372,6 +372,27 @@ static __be32 get_request_hdr(struct device *dev,
return edesc->desc.hdr1;
}
+static void dma_unmap_request(struct device *dev,
+ struct talitos_request *request, bool is_sec1)
+{
+ struct talitos_edesc *edesc;
+
+ if (is_sec1) {
+ dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+ edesc = container_of(request->desc, struct talitos_edesc, desc);
+ while (edesc->next_desc) {
+ dma_unmap_single(dev,
+ be32_to_cpu(edesc->desc.next_desc),
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ edesc = edesc->next_desc;
+ }
+ } else {
+ dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
+}
+
/*
* process what was done, notify callback of error if not
*/
@@ -379,7 +400,6 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
{
struct talitos_private *priv = dev_get_drvdata(dev);
struct talitos_request *request, saved_req;
- struct talitos_edesc *edesc;
unsigned long flags;
int tail, status;
bool is_sec1 = has_ftr_sec1(priv);
@@ -404,22 +424,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
else
status = error;
- if (is_sec1) {
- dma_unmap_single(dev, request->dma_desc,
- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
- edesc = container_of(request->desc,
- struct talitos_edesc, desc);
- while (edesc->next_desc) {
- dma_unmap_single(
- dev, be32_to_cpu(edesc->desc.next_desc),
- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
- edesc = edesc->next_desc;
- }
- } else {
- dma_unmap_single(dev, request->dma_desc,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
- }
+ dma_unmap_request(dev, request, is_sec1);
/* copy entries so we can call callback outside lock */
saved_req.desc = request->desc;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 02/11] crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
The SEC1 hardware can process a chain of descriptors without host
intervention. Only the hash implementation currently use this feature,
but with a chain of at most 2 descriptors added in commit 37b5e8897eb5
("crypto: talitos - chain in buffered data for ahash on SEC1").
Add supports for chaining an arbitrary number of descriptors in a chain.
Adapt the ahash implementation to make it compatible.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 180 ++++++++++++++++++++++++++++++++---------------
drivers/crypto/talitos.h | 2 +
2 files changed, 124 insertions(+), 58 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 440e19dc8de6..b0ebf99b94f5 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -273,7 +273,10 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
void *context, int error),
void *context)
{
+ struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
struct talitos_private *priv = dev_get_drvdata(dev);
+ dma_addr_t dma_desc, prev_dma_desc;
+ struct talitos_edesc *prev_edesc = NULL;
struct talitos_request *request;
unsigned long flags;
int head;
@@ -292,10 +295,31 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
/* map descriptor and save caller data */
if (is_sec1) {
- desc->hdr1 = desc->hdr;
- request->dma_desc = dma_map_single(dev, &desc->hdr1,
+ while (edesc) {
+ edesc->desc.hdr1 = edesc->desc.hdr;
+
+ dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
+ TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ if (!prev_edesc) {
+ request->dma_desc = dma_desc;
+ goto next;
+ }
+
+ /* Chain in any previous descriptors. */
+
+ prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
+
+ dma_sync_single_for_device(dev, prev_dma_desc,
TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
+
+next:
+ prev_edesc = edesc;
+ prev_dma_desc = dma_desc;
+ edesc = edesc->next_desc;
+ }
} else {
request->dma_desc = dma_map_single(dev, desc,
TALITOS_DESC_SIZE,
@@ -326,6 +350,7 @@ static __be32 get_request_hdr(struct device *dev,
struct talitos_request *request, bool is_sec1)
{
struct talitos_edesc *edesc;
+ dma_addr_t dma_desc;
if (!is_sec1) {
dma_sync_single_for_cpu(dev, request->dma_desc,
@@ -334,19 +359,17 @@ static __be32 get_request_hdr(struct device *dev,
return request->desc->hdr;
}
- if (!request->desc->next_desc) {
- dma_sync_single_for_cpu(dev, request->dma_desc,
- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
- return request->desc->hdr1;
- } else {
- dma_sync_single_for_cpu(dev,
- be32_to_cpu(request->desc->next_desc),
- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
- edesc = container_of(request->desc, struct talitos_edesc, desc);
-
- return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
- ->hdr1;
+ edesc = container_of(request->desc, struct talitos_edesc, desc);
+ dma_desc = request->dma_desc;
+ while (edesc->next_desc) {
+ dma_desc = be32_to_cpu(edesc->desc.next_desc);
+ edesc = edesc->next_desc;
}
+
+ dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ return edesc->desc.hdr1;
}
/*
@@ -356,6 +379,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
{
struct talitos_private *priv = dev_get_drvdata(dev);
struct talitos_request *request, saved_req;
+ struct talitos_edesc *edesc;
unsigned long flags;
int tail, status;
bool is_sec1 = has_ftr_sec1(priv);
@@ -380,9 +404,22 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
else
status = error;
- dma_unmap_single(dev, request->dma_desc,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
+ if (is_sec1) {
+ dma_unmap_single(dev, request->dma_desc,
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ edesc = container_of(request->desc,
+ struct talitos_edesc, desc);
+ while (edesc->next_desc) {
+ dma_unmap_single(
+ dev, be32_to_cpu(edesc->desc.next_desc),
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ edesc = edesc->next_desc;
+ }
+ } else {
+ dma_unmap_single(dev, request->dma_desc,
+ TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
/* copy entries so we can call callback outside lock */
saved_req.desc = request->desc;
@@ -477,8 +514,12 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
static __be32 current_desc_hdr(struct device *dev, int ch)
{
struct talitos_private *priv = dev_get_drvdata(dev);
+ bool is_sec1 = has_ftr_sec1(priv);
+ struct talitos_request *request;
+ struct talitos_edesc *edesc;
int tail, iter;
dma_addr_t cur_desc;
+ __be32 hdr = 0;
cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
@@ -489,27 +530,35 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
}
tail = priv->chan[ch].tail;
-
iter = tail;
- while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
- priv->chan[ch].fifo[iter].desc->next_desc != cpu_to_be32(cur_desc)) {
- iter = (iter + 1) & (priv->fifo_len - 1);
- if (iter == tail) {
- dev_err(dev, "couldn't locate current descriptor\n");
- return 0;
+ do {
+ request = &priv->chan[ch].fifo[iter];
+
+ if (request->dma_desc == cur_desc) {
+ hdr = request->desc->hdr;
+ } else if (is_sec1) {
+ edesc = container_of(request->desc,
+ struct talitos_edesc, desc);
+ while (edesc->next_desc) {
+ if (edesc->desc.next_desc ==
+ cpu_to_be32(cur_desc)) {
+ hdr = edesc->next_desc->desc.hdr1;
+ break;
+ }
+ edesc = edesc->next_desc;
+ }
}
- }
- if (priv->chan[ch].fifo[iter].desc->next_desc == cpu_to_be32(cur_desc)) {
- struct talitos_edesc *edesc;
+ if (hdr)
+ break;
- edesc = container_of(priv->chan[ch].fifo[iter].desc,
- struct talitos_edesc, desc);
- return ((struct talitos_desc *)
- (edesc->buf + edesc->dma_len))->hdr;
- }
+ iter = (iter + 1) & (priv->fifo_len - 1);
+ } while (iter != tail);
+
+ if (!hdr)
+ dev_err(dev, "couldn't locate current descriptor\n");
- return priv->chan[ch].fifo[iter].desc->hdr;
+ return hdr;
}
/*
@@ -1408,10 +1457,6 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
dma_len = 0;
}
alloc_len += icv_stashing ? authsize : 0;
-
- /* if its a ahash, add space for a second desc next to the first one */
- if (is_sec1 && !dst)
- alloc_len += sizeof(struct talitos_desc);
alloc_len += ivsize;
edesc = kmalloc(ALIGN(alloc_len, dma_get_cache_alignment()), flags);
@@ -1427,6 +1472,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
edesc->dst_nents = dst_nents;
edesc->iv_dma = iv_dma;
edesc->dma_len = dma_len;
+ edesc->next_desc = NULL;
if (dma_len)
edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
edesc->dma_len,
@@ -1727,8 +1773,10 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
struct talitos_desc *desc = &edesc->desc;
- struct talitos_desc *desc2 = (struct talitos_desc *)
- (edesc->buf + edesc->dma_len);
+ struct talitos_desc *desc2;
+
+ if (desc->next_desc)
+ desc2 = &edesc->next_desc->desc;
unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
if (desc->next_desc &&
@@ -1756,10 +1804,17 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
DMA_BIDIRECTIONAL);
+}
- if (desc->next_desc)
- dma_unmap_single(dev, be32_to_cpu(desc->next_desc),
- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+static void free_edesc_list_from(struct talitos_edesc *edesc)
+{
+ struct talitos_edesc *next;
+
+ while (edesc) {
+ next = edesc->next_desc;
+ kfree(edesc);
+ edesc = next;
+ }
}
static void ahash_done(struct device *dev,
@@ -1778,7 +1833,7 @@ static void ahash_done(struct device *dev,
}
common_nonsnoop_hash_unmap(dev, edesc, areq);
- kfree(edesc);
+ free_edesc_list_from(edesc);
if (err) {
ahash_request_complete(areq, err);
@@ -1894,14 +1949,23 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
if (is_sec1 && req_ctx->nbuf && length) {
- struct talitos_desc *desc2 = (struct talitos_desc *)
- (edesc->buf + edesc->dma_len);
- dma_addr_t next_desc;
+ struct talitos_edesc *edesc2;
+ struct talitos_desc *desc2;
+
+ edesc2 = kzalloc(sizeof(*edesc2),
+ areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+ GFP_KERNEL :
+ GFP_ATOMIC);
+ if (!edesc2) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ edesc->next_desc = edesc2;
+
+ desc2 = &edesc2->desc;
- memset(desc2, 0, sizeof(*desc2));
desc2->hdr = desc->hdr;
desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
- desc2->hdr1 = desc2->hdr;
desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
@@ -1925,21 +1989,21 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
req_ctx->hw_context_size,
req_ctx->hw_context,
DMA_FROM_DEVICE);
-
- next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
- desc->next_desc = cpu_to_be32(next_desc);
}
if (sync_needed)
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
- ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
- if (ret != -EINPROGRESS) {
- common_nonsnoop_hash_unmap(dev, edesc, areq);
- kfree(edesc);
- }
+ ret = talitos_submit(dev, ctx->ch, desc, callback,
+ areq);
+ if (ret != -EINPROGRESS)
+ goto err;
+
+ return -EINPROGRESS;
+err:
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+ kfree(edesc);
return ret;
}
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 1a93ee355929..596f96bba3ef 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -49,6 +49,7 @@ struct talitos_desc {
* @iv_dma: dma address of iv for checking continuity and link table
* @dma_len: length of dma mapped link_tbl space
* @dma_link_tbl: bus physical address of link_tbl/buf
+ * @next_desc: next descriptor
* @desc: h/w descriptor
* @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
* @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
@@ -63,6 +64,7 @@ struct talitos_edesc {
dma_addr_t iv_dma;
int dma_len;
dma_addr_t dma_link_tbl;
+ struct talitos_edesc *next_desc;
struct talitos_desc desc;
union {
DECLARE_FLEX_ARRAY(struct talitos_ptr, link_tbl);
--
2.54.0
^ permalink raw reply related
* [PATCH v3 01/11] crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
In order to know if a descriptor has been processed by the device,
the driver polls the FIFO to see if DESC_HDR_DONE is set on a descriptor
header to confirm completion.
The current code does not make sure that the CPU gets up to date data
before reading the descriptor.
Fix this by calling dma_sync_single_for_cpu() before reading memory
written by the device.
Cc: stable@vger.kernel.org
Fixes: 58cdbc6d2263 ("crypto: talitos - fix hash on SEC1.")
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bc61d0fe3514..440e19dc8de6 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -322,19 +322,31 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
return -EINPROGRESS;
}
-static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1)
+static __be32 get_request_hdr(struct device *dev,
+ struct talitos_request *request, bool is_sec1)
{
struct talitos_edesc *edesc;
- if (!is_sec1)
+ if (!is_sec1) {
+ dma_sync_single_for_cpu(dev, request->dma_desc,
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+
return request->desc->hdr;
+ }
- if (!request->desc->next_desc)
+ if (!request->desc->next_desc) {
+ dma_sync_single_for_cpu(dev, request->dma_desc,
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
return request->desc->hdr1;
+ } else {
+ dma_sync_single_for_cpu(dev,
+ be32_to_cpu(request->desc->next_desc),
+ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ edesc = container_of(request->desc, struct talitos_edesc, desc);
- edesc = container_of(request->desc, struct talitos_edesc, desc);
-
- return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1;
+ return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
+ ->hdr1;
+ }
}
/*
@@ -358,7 +370,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
/* descriptors with their done bits set don't get the error */
rmb();
- hdr = get_request_hdr(request, is_sec1);
+ hdr = get_request_hdr(dev, request, is_sec1);
if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
status = 0;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 00/11] crypto: talitos - fix several issues in the Freescale talitos crypto driver
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
This series fixes several issues in the Freescale talitos crypto driver.
Patch 1 fixes a missing dma_sync_single_for_cpu() before reading a
descriptor header.
Patches 2-5 add support for chaining an arbitrary number of descriptors
in the driver for the SEC1 hardware.
Patches 6-8 rework the SEC1 hash implementation to build descriptor
chains instead of submitting one descriptor at a time via a workqueue.
Patches 9-10 are cleanups: rename first_desc/last_desc to
first_request/last_request, and remove a useless wrapper function.
Patch 11 fixes the same ahash request size limitation on SEC2 (64k - 1
bytes), by splitting ahash_done() into SEC1 and SEC2 paths so that SEC2
iterates through descriptors sequentially.
Tested on an MPC885 SoC (SEC1 Lite), and on an MPC8321EMP SoC (SEC2)
with CRYPTO_SELFTESTS_FULL=y.
For the SEC1 Lite, some tests are failing due to a timeout waiting for
request completion. These failed tests existed prior to this series.
On SEC2, there is no failed tests.
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
Changes in v3:
- Patch 1 was reading the next chained descriptor header
unconditionally. Fixed it by checking if a request actually contained
a chained descriptor before deferencing it.
- For descriptor chaining introduced in patch 2, use a next pointer
embedded inside struct talitos_edesc instead of the kernel's struct
list_node. This removes the necessity for a desc_chain member in
struct talitos_request. A dirty hack was previously used to assign a
request->desc_chain to the current request by taking edesc->prev,
assuming that the descriptor was added to a list before calling
talitos_submit(). Not only was this non-idiomatic, but it also broke
the skcipher and aead implementations because they do not use the
descriptor chaining feature at all. The descriptor chaining mechanism
does not need a doubly circular linked list; this change makes the
code more readable than sticking with the kernel linked list
implementation.
- Updated the performance measurement in patch 6.
- Drop patch 12, which was a revert of commit 4b24ea971a93 ("crypto:
talitos - Preempt overflow interrupts off-by-one fix"). This patch was
primarily motivated because the SEC1 has a Fetch Register rather than
a Fetch FIFO per channel. As a result, having a value of 24 in the
device tree node for the channel-fifo-len property does not make
sense, as the hardware does not have a Fetch FIFO. Setting this value
to 1 (which should be the correct value for SoCs featuring the SEC1
engine family) breaks the driver because no descriptor can be
submitted due to commit 4b24ea971a93, and the patch was primarily
intended to fix this issue. As this issue is too deep to be addressed
in this patch series, it has been dropped.
- Link to v2: https://patch.msgid.link/20260505-bootlin_test-7-1-rc1_sec_bugfix-v2-0-5818064bd190@bootlin.com
Changes in v2:
- Split the first patch into smaller, logically separated patches for
easier review.
- Added more context on testing on the cover letter.
- Introduce a fix to correctly read hardware descriptor header. This fix
was motivated by a remark of Sashiko on the v1:
https://sashiko.dev/#/patchset/20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5%40bootlin.com
- Separate SEC2 64k-1 ahash limitation fix into its own patch.
- Link to v1: https://patch.msgid.link/20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com
To: Herbert Xu <herbert@gondor.apana.org.au>
To: "David S. Miller" <davem@davemloft.net>
To: Christophe Leroy <chleroy@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: David Howells <dhowells@redhat.com>
Cc: linux-crypto@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
Paul Louvel (11):
crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1
crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function
crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
crypto: talitos - move code in current_desc_hdr() into a standalone function
crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor
crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue
crypto: talitos/hash - drop workqueue mechanism for SEC1
crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request
crypto: talitos/hash - remove useless wrapper
crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation
drivers/crypto/talitos.c | 549 ++++++++++++++++++++++++-----------------------
drivers/crypto/talitos.h | 12 ++
2 files changed, 287 insertions(+), 274 deletions(-)
---
base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc
Best regards,
--
Paul Louvel <paul.louvel@bootlin.com>
^ permalink raw reply
* Re: [PATCH v2 00/12] crypto: talitos - fix several issues in the Freescale talitos crypto driver
From: Paul Louvel @ 2026-05-07 14:40 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
stable
In-Reply-To: <20260505-bootlin_test-7-1-rc1_sec_bugfix-v2-0-5818064bd190@bootlin.com>
Again, some issues breaking existing crypto implementation in the driver have
been found upon Sashiko's review.
Please discard this v2.
Many thanks,
On 5/5/26 7:53 PM, Paul Louvel wrote:
> This series fixes several issues in the Freescale talitos crypto driver.
>
> Patch 1 fixes a missing dma_sync_single_for_cpu() before reading a
> descriptor header.
>
> Patches 2-5 add support for chaining an arbitrary number of descriptors
> in the driver for the SEC1 hardware.
>
> Patches 6-9 rework the SEC1 hash implementation to build descriptor
> chains instead of submitting one descriptor at a time via a workqueue.
>
> Patch 10 fixes the same ahash request size limitation on SEC2 (64k - 1
> bytes), by splitting ahash_done() into SEC1 and SEC2 paths so that SEC2
> iterates through descriptors sequentially.
>
> Patch 11 fixes an off-by-one in the submit_count initialisation that
> wastes one FIFO slot.
>
> Tested on an MPC885 SoC (SEC1 Lite), and on an MPC8321EMP SoC (SEC2)
> with CRYPTO_SELFTESTS_FULL=y.
> For the SEC1 Lite, some tests are failing due to a timeout waiting for
> request completion. These failed tests existed prior to this series.
> On SEC2, there is no failed tests.
>
> Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
> ---
> Changes in v2:
> - Split the first patch into smaller, logically separated patches for
> easier review.
> - Added more context on testing on the cover letter.
> - Introduce a fix to correctly read hardware descriptor header. This fix
> was motivated by a remark of Sashiko on the v1:
> https://sashiko.dev/#/patchset/20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5%40bootlin.com
> - Separate SEC2 64k-1 ahash limitation fix into its own patch.
> - Link to v1: https://patch.msgid.link/20260504-bootlin_test-7-1-rc1_sec_bugfix-v1-0-c97c641976f5@bootlin.com
>
> ---
> Paul Louvel (12):
> crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
> crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1
> crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function
> crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
> crypto: talitos - move code in current_desc_hdr() into a standalone function
> crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor
> crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue
> crypto: talitos/hash - drop workqueue mechanism for SEC1
> crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request
> crypto: talitos/hash - remove useless wrapper
> crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation
> crypto: talitos - fix invalid submit_count initial value
>
> drivers/crypto/talitos.c | 578 ++++++++++++++++++++++++-----------------------
> drivers/crypto/talitos.h | 14 ++
> 2 files changed, 315 insertions(+), 277 deletions(-)
> ---
> base-commit: db8b9f227833e729faf44a512aa1e88a625b5ad8
> change-id: 20260504-bootlin_test-7-1-rc1_sec_bugfix-13169ed07ddc
>
> Best regards,
> --
> Paul Louvel <paul.louvel@bootlin.com>
>
--
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH] crypto: atmel-ecc - replace min_t with min
From: Thorsten Blum @ 2026-05-07 13:55 UTC (permalink / raw)
To: Thorsten Blum, Herbert Xu, David S. Miller, Nicolas Ferre,
Alexandre Belloni, Claudiu Beznea
Cc: linux-crypto, linux-arm-kernel, linux-kernel
Use the simpler min() macro since the values are all unsigned and
compatible.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
drivers/crypto/atmel-ecc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index b6a77c8d439c..2cf53f0b6742 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -56,7 +56,7 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
goto free_work_data;
/* might want less than we've got */
- n_sz = min_t(size_t, ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
+ n_sz = min(ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
/* copy the shared secret */
copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, n_sz),
@@ -150,7 +150,7 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
return -EINVAL;
/* might want less than we've got */
- nbytes = min_t(size_t, ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
+ nbytes = min(ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
/* public key was saved at private key generation */
copied = sg_copy_from_buffer(req->dst,
^ permalink raw reply related
* [PATCH v2 1/3] dt-bindings: crypto: qcom,ice: Add sa8255p support
From: Linlin Zhang @ 2026-05-07 11:24 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Herbert Xu, David S . Miller, Bjorn Andersson, devicetree,
linux-crypto, linux-arm-msm, linux-kernel
In-Reply-To: <20260507112454.2527088-1-linlin.zhang@oss.qualcomm.com>
On sa8255p, resources such as PHY, clocks, regulators, and resets are
managed by remote firmware via the SCMI power protocol. As a result, the
ICE driver cannot directly access clocks and must instead use power-domains
to request resource configuration.
Add the qcom,sa8255p-inline-crypto-engine compatible string and make clocks
optional for platforms that use power-domains instead.
Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
---
.../crypto/qcom,inline-crypto-engine.yaml | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
index 876bf90ed96e..4e7d9111d0eb 100644
--- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
+++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
@@ -17,6 +17,7 @@ properties:
- qcom,kaanapali-inline-crypto-engine
- qcom,milos-inline-crypto-engine
- qcom,qcs8300-inline-crypto-engine
+ - qcom,sa8255p-inline-crypto-engine
- qcom,sa8775p-inline-crypto-engine
- qcom,sc7180-inline-crypto-engine
- qcom,sc7280-inline-crypto-engine
@@ -32,6 +33,9 @@ properties:
clocks:
maxItems: 1
+ power-domains:
+ maxItems: 1
+
operating-points-v2: true
opp-table:
@@ -40,7 +44,20 @@ properties:
required:
- compatible
- reg
- - clocks
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sa8255p-inline-crypto-engine
+ then:
+ required:
+ - power-domains
+ else:
+ required:
+ - clocks
additionalProperties: false
@@ -75,4 +92,12 @@ examples:
};
};
};
+
+ - |
+ crypto@1d88000 {
+ compatible = "qcom,sa8255p-inline-crypto-engine",
+ "qcom,inline-crypto-engine";
+ reg = <0x01d88000 0x8000>;
+ power-domains = <&scmi26_pd 0>;
+ };
...
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/3] soc: qcom: ice: Enable firmware managed resource
From: Linlin Zhang @ 2026-05-07 11:24 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Herbert Xu, David S . Miller, Bjorn Andersson, devicetree,
linux-crypto, linux-arm-msm, linux-kernel
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 2610 bytes --]
From: linlzhan <linlzhan@qti.qualcomm.com>
The Qualcomm automotive SA8255p SoC relies on firmware to configure
platform resources, including clocks, interconnects and TLMM (GPIOs).
These resources are controlled by the driver via SCMI power and
performance protocols.
The SCMI power protocol is used to enable and disable platform
resources, including clocks, interconnect paths, and TLMM, by mapping
resource state transitions to the runtime PM frameworks
resume/suspend callbacks.
In this design, the ICE driver acts as an SCMI client, with clocks and
power domains abstracted and controlled by the SCMI server in firmware.
This implementation depends on pm_runtime_resume_and_get() and
pm_runtime_put_sync(), which are available in the OPP trees
linux-next branch.
v2:
-- rebase the patchset
-- update to/cc lists
-- Link to v1: https://lore.kernel.org/all/20260430032136.3058773-1-linlin.zhang@oss.qualcomm.com/
-- To Linux Community
v6:
- Protect calling clock API with fw_managed flag in ICE runtime OPS callbacks.
- Link to v5: http://shc-kerarch-hyd:8080/kernel_archive/20260324095703.1306437-1-linlin.zhang@oss.qualcomm.com/T/#t
v5:
- Align the continued argument line under the first argument after left parenthesis.
- Modify the return value in probe function.
- Link to v4: http://shc-kerarch-hyd:8080/kernel_archive/20260318170626.3654744-1-linlin.zhang@oss.qualcomm.com/T/
v4:
- Commit and signed-off by OSS mail id
- Enable runtime PM for ICE dirver
- Add driver data to diffrenciate the clock managed by the firmware or not
- Link to v3: http://shc-kerarch-hyd:8080/kernel_archive/20251107091315.476074-1-quic_linlzhan@quicinc.com/
v3:
- Update the subject of patch 2.
- Update returned type of remvoe function and firmware flag in ICE diver.
- Link to v2: http://shc-kerarch-hyd:8080/kernel_archive/20251104104935.2752144-1-quic_linlzhan@quicinc.com/T/#t
v2:
- Addresssed comments from Badgey
- Make Document binding of ice pass for binding checking.
- Link to v1: http://shc-kerarch-hyd:8080/kernel_archive/20251024050921.3573402-1-quic_linlzhan@quicinc.com/T/#t
Initial version:
- Add fw managed resource abstraction support in ICE driver.
- Add respective compatible and document it's bindings.
Linlin Zhang (3):
dt-bindings: crypto: qcom,ice: Add sa8255p support
soc: qcom: ice: Enable PM runtime for ICE driver
soc: qcom: ice: Add SCMI support for sa8255p based targets
.../crypto/qcom,inline-crypto-engine.yaml | 27 ++++-
drivers/soc/qcom/ice.c | 108 +++++++++++++++---
2 files changed, 115 insertions(+), 20 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH v5 01/13] dt-bindings: crypto: qcom,ice: Fix missing power-domain and iface clk
From: Harshal Dev @ 2026-05-07 10:20 UTC (permalink / raw)
To: Bjorn Andersson
Cc: David S. Miller, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Abel Vesa, Manivannan Sadhasivam,
cros-qcom-dts-watchers, Eric Biggers, Dmitry Baryshkov,
Jingyi Wang, Tengfei Fan, Bartosz Golaszewski, David Wronek,
Luca Weiss, Neil Armstrong, Melody Olvera, Alexander Koskovich,
Abel Vesa, Brian Masney, Neeraj Soni, Gaurav Kashyap,
linux-arm-msm, linux-crypto, devicetree, linux-kernel,
Krzysztof Kozlowski, Konrad Dybcio, Kuldeep Singh,
Krzysztof Kozlowski, Herbert Xu
In-Reply-To: <afmuncmBrrvddHTU@gondor.apana.org.au>
Hi Bjorn,
On 5/5/2026 2:17 PM, Herbert Xu wrote:
> On Thu, Apr 16, 2026 at 05:29:18PM +0530, Harshal Dev wrote:
>> The DT bindings for inline-crypto engine do not specify the UFS_PHY_GDSC
>> power-domain and iface clock. Without enabling the iface clock and the
>> associated power-domain the ICE hardware cannot function correctly and
>> leads to unclocked hardware accesses being observed during probe.
>>
>> Fix the DT bindings for inline-crypto engine to require the UFS_PHY_GDSC
>> power-domain and iface clock for new devices (Eliza and Milos) introduced
>> in the current release (7.1) with yet-to-stabilize ABI, while preserving
>> backward compatibility for older devices.
>>
>> Fixes: 618195a7ac3df ("dt-bindings: crypto: qcom,inline-crypto-engine: Document the Eliza ICE")
>> Fixes: 85faec1e85555 ("dt-bindings: crypto: qcom,inline-crypto-engine: document the Milos ICE")
>> Reviewed-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>> Signed-off-by: Harshal Dev <harshal.dev@oss.qualcomm.com>
>> ---
>> .../bindings/crypto/qcom,inline-crypto-engine.yaml | 35 +++++++++++++++++++++-
>> 1 file changed, 34 insertions(+), 1 deletion(-)
>
> Patch applied. Thanks.
Herbert has pulled out of picking this patch from his tree.
As discussed, since this DT binding update relies on DTS changes in commits 12 and 13
of these series, they should all go through the same tree.
Can we aim to pick this series via the qcom-soc tree to ensure the binding and DTS changes
are applied together? Since the 7.1 fixes window is open, I am hoping for this to be
picked up this week or the next.
Regards,
Harshal
^ permalink raw reply
* Re: [PATCH v6 1/3] dt-bindings: crypto: qcom,ice: Add sa8255p support
From: Linlin Zhang @ 2026-05-07 9:59 UTC (permalink / raw)
To: Krzysztof Kozlowski, linux-arm-msm, linux-crypto, linux-kernel,
ebiggers
Cc: neeraj.soni, gaurav.kashyap, deepti.jaggi, bjorn.andersson,
quic_shazhuss, trilok.soni, konrad.dybcio
In-Reply-To: <41da4b77-4d0d-48bd-9578-2adefe5466af@kernel.org>
On 4/30/2026 2:13 PM, Krzysztof Kozlowski wrote:
> On 30/04/2026 05:21, Linlin Zhang wrote:
>> On sa8255p, resources such as PHY, clocks, regulators, and resets are
>> managed by remote firmware via the SCMI power protocol. As a result, the
>> ICE driver cannot directly access clocks and must instead use power-domains
>> to request resource configuration.
>>
>> Add the qcom,sa8255p-inline-crypto-engine compatible string and make clocks
>> optional for platforms that use power-domains instead.
>
>
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
>
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline) or work on fork of kernel
> (don't, instead use mainline). Just use b4 and everything should be
> fine, although remember about `b4 prep --auto-to-cc` if you added new
> patches to the patchset.
>
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time.
>
> Please kindly resend and include all necessary To/Cc entries.
Thanks for your guide!
I'll send a new patchset on top of the latest kernel version
(branch: next-20260506) and update the to/cc list based on the list of
scripts/get_maintainer.pl output.
>
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH v16 00/12] crypto/dmaengine: qce: introduce BAM locking and use DMA for register I/O
From: Manivannan Sadhasivam @ 2026-05-07 9:55 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Vinod Koul, Jonathan Corbet, Thara Gopinath, Herbert Xu,
David S. Miller, Udit Tiwari, Md Sadre Alam, Dmitry Baryshkov,
Stephan Gerhold, Bjorn Andersson, Peter Ujfalusi, Michal Simek,
Frank Li, dmaengine, linux-doc, linux-kernel, linux-arm-msm,
linux-crypto, linux-arm-kernel, brgl, Bartosz Golaszewski,
Dmitry Baryshkov, Konrad Dybcio
In-Reply-To: <20260427-qcom-qce-cmd-descr-v16-0-945fd1cafbbc@oss.qualcomm.com>
On Mon, Apr 27, 2026 at 11:15:33AM +0200, Bartosz Golaszewski wrote:
> This missed the v7.1 cycle so let's try to get it in for v7.2.
>
> 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.
>
> This iteration continues to build on top of v12 but uses the BAM's NWD
> bit on data descriptors as suggested by Stephan. To that end, there are
> some more changes like reversing the order of command and data
> descriptors queuedy by the QCE driver.
>
> 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.
>
> Shout out to Daniel and Udit from Qualcomm for helping me out with some
> DMA issues we encountered.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
For the whole series,
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Thanks for incorporating all the comments, Bart!
- Mani
> ---
> 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/20260402-qcom-qce-cmd-descr-v15-0-98b5361f7ed7@oss.qualcomm.com
>
> 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/20260323-qcom-qce-cmd-descr-v14-0-f323af411274@oss.qualcomm.com
>
> 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/20260317-qcom-qce-cmd-descr-v13-0-0968eb4f8c40@oss.qualcomm.com
>
> 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/20260310-qcom-qce-cmd-descr-v12-0-398f37f26ef0@oss.qualcomm.com
>
> 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/20260302-qcom-qce-cmd-descr-v11-0-4bf1f5db4802@oss.qualcomm.com
>
> 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/20251219-qcom-qce-cmd-descr-v10-0-ff7e4bf7dad4@oss.qualcomm.com
>
> 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/20251128-qcom-qce-cmd-descr-v9-0-9a5f72b89722@linaro.org
>
> 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/20251106-qcom-qce-cmd-descr-v8-0-ecddca23ca26@linaro.org
>
> 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/20250311-qce-cmd-descr-v7-0-db613f5d9c9f@linaro.org/
>
> 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/20250115103004.3350561-1-quic_mdalam@quicinc.com/
>
> 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/183d4f5e-e00a-8ef6-a589-f5704bc83d4a@quicinc.com/
> - 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/20231214114239.2635325-1-quic_mdalam@quicinc.com/
> - 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 (12):
> dmaengine: constify struct dma_descriptor_metadata_ops
> 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 - 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 | 8 +-
> drivers/crypto/qce/common.c | 20 ++--
> drivers/crypto/qce/core.c | 28 ++++-
> drivers/crypto/qce/core.h | 11 ++
> drivers/crypto/qce/dma.c | 163 +++++++++++++++++++++++------
> drivers/crypto/qce/dma.h | 11 +-
> drivers/crypto/qce/sha.c | 8 +-
> drivers/crypto/qce/skcipher.c | 8 +-
> drivers/dma/qcom/bam_dma.c | 217 ++++++++++++++++++++++++++++++++++-----
> drivers/dma/ti/k3-udma.c | 2 +-
> drivers/dma/xilinx/xilinx_dma.c | 2 +-
> include/linux/dma/qcom_bam_dma.h | 14 +++
> include/linux/dmaengine.h | 2 +-
> 13 files changed, 404 insertions(+), 90 deletions(-)
> ---
> base-commit: 06ae5ec2a5f35da6b24d404d16310ee3553dba6f
> change-id: 20251103-qcom-qce-cmd-descr-c5e9b11fe609
>
> Best regards,
> --
> Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v2] crypto: ecc - Unbreak the build on arm with CONFIG_KASAN_STACK=y
From: Andy Shevchenko @ 2026-05-07 9:26 UTC (permalink / raw)
To: Herbert Xu
Cc: Lukas Wunner, David S. Miller, Andrew Morton, Arnd Bergmann,
Andrey Ryabinin, Ignat Korchagin, Stefan Berger, linux-crypto,
linux-kernel, kasan-dev, Alexander Potapenko, Andrey Konovalov,
Dmitry Vyukov, Vincenzo Frascino, Eric Biggers, Nathan Chancellor,
David Laight, Jason A. Donenfeld, Ard Biesheuvel
In-Reply-To: <afwUYlGYZH5cSbg3@gondor.apana.org.au>
On Thu, May 07, 2026 at 12:26:10PM +0800, Herbert Xu wrote:
> On Wed, May 06, 2026 at 03:27:49PM +0200, Lukas Wunner wrote:
> >
> > Changes v1 -> v2:
> > * s/ARCH/CONFIG_ARM/, s/LLVM/CONFIG_CC_IS_GCC/ (Nathan)
> > * Add link to gcc bugzilla entry
> > * Rewrite commit message to include feedback provided by gcc maintainers
> > and explain high stack usage with algorithm choice
> >
> > Link to v1:
> > https://lore.kernel.org/r/abfaede9ab2e963d784fb70598ed74935f7f8d93.1775628469.git.lukas@wunner.de/
> >
> > crypto/Makefile | 5 +++++
> > 1 file changed, 5 insertions(+)
>
> Sorry but v1 has already been applied.
Does it make sense to revert and apply v2?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH] crypto: ecc - Unbreak the build on arm with CONFIG_KASAN_STACK=y
From: Herbert Xu @ 2026-05-07 8:11 UTC (permalink / raw)
To: Lukas Wunner
Cc: David S. Miller, Andrew Morton, Arnd Bergmann, Andrey Ryabinin,
Ignat Korchagin, Stefan Berger, linux-crypto, linux-kernel,
kasan-dev, Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Andy Shevchenko
In-Reply-To: <aftFAexDFrYbIeBM@wunner.de>
On Wed, May 06, 2026 at 03:41:21PM +0200, Lukas Wunner wrote:
>
> My apologies Herbert, I was working on a v2 for this patch
> but unfortunately didn't finish it until today:
>
> https://lore.kernel.org/r/7e3d64a53efb28740b32d1f934e78c10086208ab.1778073318.git.lukas@wunner.de/
>
> Would it be possible for you to replace the patch you've already applied
> with the new one? I am very sorry for the hassle.
OK I've backed it out for now.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v2] crypto: ecc - Unbreak the build on arm with CONFIG_KASAN_STACK=y
From: Herbert Xu @ 2026-05-07 4:26 UTC (permalink / raw)
To: Lukas Wunner
Cc: David S. Miller, Andrew Morton, Arnd Bergmann, Andrey Ryabinin,
Ignat Korchagin, Stefan Berger, linux-crypto, linux-kernel,
kasan-dev, Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Andy Shevchenko, Eric Biggers,
Nathan Chancellor, David Laight, Jason A. Donenfeld,
Ard Biesheuvel
In-Reply-To: <7e3d64a53efb28740b32d1f934e78c10086208ab.1778073318.git.lukas@wunner.de>
On Wed, May 06, 2026 at 03:27:49PM +0200, Lukas Wunner wrote:
>
> Changes v1 -> v2:
> * s/ARCH/CONFIG_ARM/, s/LLVM/CONFIG_CC_IS_GCC/ (Nathan)
> * Add link to gcc bugzilla entry
> * Rewrite commit message to include feedback provided by gcc maintainers
> and explain high stack usage with algorithm choice
>
> Link to v1:
> https://lore.kernel.org/r/abfaede9ab2e963d784fb70598ed74935f7f8d93.1775628469.git.lukas@wunner.de/
>
> crypto/Makefile | 5 +++++
> 1 file changed, 5 insertions(+)
Sorry but v1 has already been applied.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: powernv_rng_read: Oops: Kernel access of bad area, sig: 11 [#1]
From: Madhavan Srinivasan @ 2026-05-07 2:40 UTC (permalink / raw)
To: Paul Menzel, Olivia Mackall, Herbert Xu, Michael Ellerman
Cc: linux-crypto, linuxppc-dev, LKML
In-Reply-To: <a159e81a-ccfd-440f-af68-6a56cca09cb2@molgen.mpg.de>
On 5/6/26 7:31 PM, Paul Menzel wrote:
> Dear Linux folks,
>
>
> After a long while, on the 8335-GCA POWER8 (raw) 0x4d0200
> opal:skiboot-5.4.8-5787ad3 PowerNV, I built Linux from Linus’ master
> branch and rebooted via kexec.
>
> ```
> [ 0.000000] Linux version 7.1.0-rc2+
> (pmenzel@flughafenberlinbrandenburgwillybrandt.molgen.mpg.de) (gcc
> (Ubuntu 11.2.0-7ubuntu2) 11.2.0, GNU ld (GNU Binutils for Ubuntu)
> 2.37) #3 SMP PREEMPT Wed May 6 08:50:58 CEST 2026
> […]
> [ 17.901992] Kernel attempted to read user page (0) - exploit
> attempt? (uid: 0)
> [ 17.902011] BUG: Kernel NULL pointer dereference on read at 0x00000000
> [ 17.902018] Faulting instruction address: 0xc0000000000e7138
> [ 17.902027] Oops: Kernel access of bad area, sig: 11 [#1]
> [ 17.902034] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA PowerNV
> [ 17.902045] Modules linked in: powernv_rng(+) bnx2x ofpart
> ibmpowernv bfq mdio cmdlinepart powernv_flash ipmi_powernv
> ipmi_devintf mtd ipmi_msghandler at24(+) vmx_crypto opal_prd
> sch_fq_codel nfsd parport_pc ppdev auth_rpcgss nfs_acl lp lockd grace
> parport sunrpc autofs4 btrfs xor libblake2b raid6_pq ast
> drm_shmem_helper drm_client_lib i2c_algo_bit drm_kms_helper drm ahci
> drm_panel_orientation_quirks libahci
> [ 17.902185] CPU: 147 UID: 0 PID: 2626 Comm: hwrng Not tainted
> 7.1.0-rc2+ #3 PREEMPTLAZY
> [ 17.902197] Hardware name: 8335-GCA POWER8 (raw) 0x4d0200
> opal:skiboot-5.4.8-5787ad3 PowerNV
> [ 17.902204] NIP: c0000000000e7138 LR: c00800001ec8013c CTR:
> c0000000000e70fc
> [ 17.902212] REGS: c000000092913c50 TRAP: 0300 Not tainted
> (7.1.0-rc2+)
> [ 17.902222] MSR: 900000000280b033
> <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 44420220 XER: 20000000
> [ 17.902269] CFAR: c00800001ec8026c DAR: 0000000000000000 DSISR:
> 40000000 IRQMASK: 0
> GPR00: c00800001ec8013c c000000092913ef0
> c000000001c18100 c00000002222d900
> GPR04: c00000002222d900 0000000000000080
> 0000000000000001 0000000000000000
> GPR08: 0000000000000000 c000000002212000
> c0000000951e1780 c00800001ec80258
> GPR12: c0000000000e70fc c00000ffff6fd700
> c0000000001d11c0 c00000001b99b9c0
> GPR16: 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> GPR20: 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> GPR24: 0000000000000000 c000000002fe6a58
> 0000000000000000 0000000000000000
> GPR28: c000000002fe6a20 0000000000000010
> 000000000000000f c00000002222d900
> [ 17.902406] NIP [c0000000000e7138] pnv_get_random_long+0x3c/0x114
> [ 17.902426] LR [c00800001ec8013c] powernv_rng_read+0x78/0xc4
> [powernv_rng]
> [ 17.902444] Call Trace:
> [ 17.902448] [c000000092913ef0] [c000000092913f30]
> 0xc000000092913f30 (unreliable)
> [ 17.902463] [c000000092913f30] [c000000000decd58]
> hwrng_fillfn+0xd4/0x3dc
> [ 17.902484] [c000000092913f90] [c0000000001d1328] kthread+0x170/0x1a4
> [ 17.902498] [c000000092913fe0] [c00000000000d030]
> start_kernel_thread+0x14/0x18
> [ 17.902513] Code: 60000000 7d2000a6 71290010 418200bc e94d0908
> 812a0000 39290001 912a0000 e90d0030 3d220060 39299f00 7d08482a
> <e9280000> 7c0004ac e8e90000 0c070000
> [ 17.902569] ---[ end trace 0000000000000000 ]---
> [ 18.008801] pstore: backend (nvram) writing error (-1)
>
> [ 18.015458] note: hwrng[2626] exited with irqs disabled
> [ 18.015483] note: hwrng[2626] exited with preempt_count 1
> ```
>
> Please find the output of `dmesg` attached.
This is from my yesterday's boot test log in my P8, did not see this fail.
root@ltcppm1:~# uname -a
Linux ltcppm1.ltc.tadn.ibm.com 7.1.0-rc2-00021-gf583bd5f64d4 #1 SMP
PREEMPT Wed May 6 00:55:45 EDT 2026 ppc64le GNU/Linux
root@ltcppm1:~# dmesg
[ 0.000000] [ T0] random: crng init done
[ 0.000000] [ T0] hash-mmu: Page sizes from device-tree:
[ 0.000000] [ T0] hash-mmu: base_shift=12: shift=12,
sllp=0x0000, avpnm=0x00000000, tlbiel=1, penc=0
[ 0.000000] [ T0] hash-mmu: base_shift=12: shift=16,
sllp=0x0000, avpnm=0x00000000, tlbiel=1, penc=7
[ 0.000000] [ T0] hash-mmu: base_shift=12: shift=24,
sllp=0x0000, avpnm=0x00000000, tlbiel=1, penc=56
[ 0.000000] [ T0] hash-mmu: base_shift=16: shift=16,
sllp=0x0110, avpnm=0x00000000, tlbiel=1, penc=1
[ 0.000000] [ T0] hash-mmu: base_shift=16: shift=24,
sllp=0x0110, avpnm=0x00000000, tlbiel=1, penc=8
[ 0.000000] [ T0] hash-mmu: base_shift=24: shift=24,
sllp=0x0100, avpnm=0x00000001, tlbiel=0, penc=0
[ 0.000000] [ T0] hash-mmu: base_shift=34: shift=34,
sllp=0x0120, avpnm=0x000007ff, tlbiel=0, penc=3
[ 0.000000] [ T0] Enabling pkeys with max key count 32
[ 0.000000] [ T0] Activating Kernel Userspace Access Prevention
[ 0.000000] [ T0] Activating Kernel Userspace Execution Prevention
[ 0.000000] [ T0] hash-mmu: Page orders: linear mapping = 24,
virtual = 16, io = 16, vmemmap = 24
[ 0.000000] [ T0] hash-mmu: Using 1TB segments
[ 0.000000] [ T0] hash-mmu: Initializing hash mmu with SLB
[ 0.000000] [ T0] Linux version 7.1.0-rc2-00021-gf583bd5f64d4
(root@ltcppm1.ltc.tadn.ibm.com) (gcc (GCC) 16.1.1 20260501 (Red Hat
16.1.1-1), GNU ld version 2.46-1.fc44) #1 SMP PREEMPT Wed May 6
00:55:45 EDT 2026
[ 0.000000] [ T0] OF: reserved mem:
0x0000000039c00000..0x000000003b6801ff (27136 KiB) map non-reusable
ibm,firmware-allocs-memory@39c00000
[ 0.000000] [ T0] OF: reserved mem:
0x0000000800000000..0x0000000800e801ff (14848 KiB) map non-reusable
ibm,firmware-allocs-memory@800000000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001000000000..0x0000001000dc01ff (14080 KiB) map non-reusable
ibm,firmware-allocs-memory@1000000000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001800000000..0x0000001800e801ff (14848 KiB) map non-reusable
ibm,firmware-allocs-memory@1800000000
[ 0.000000] [ T0] OF: reserved mem:
0x0000000030000000..0x00000000302fffff (3072 KiB) map non-reusable
ibm,firmware-code@30000000
[ 0.000000] [ T0] OF: reserved mem:
0x0000000031000000..0x0000000031bfffff (12288 KiB) map non-reusable
ibm,firmware-data@31000000
[ 0.000000] [ T0] OF: reserved mem:
0x0000000030300000..0x0000000030ffffff (13312 KiB) map non-reusable
ibm,firmware-heap@30300000
[ 0.000000] [ T0] OF: reserved mem:
0x0000000031c00000..0x0000000033fdffff (36736 KiB) map non-reusable
ibm,firmware-stacks@31c00000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffd510000..0x0000001ffd69ffff (1600 KiB) map non-reusable
ibm,hbrt-code-image@1ffd510000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffd6a0000..0x0000001ffd6fffff (384 KiB) map non-reusable
ibm,hbrt-target-image@1ffd6a0000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffd700000..0x0000001ffd7fffff (1024 KiB) map non-reusable
ibm,hbrt-vpd-image@1ffd700000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffda00000..0x0000001ffdafffff (1024 KiB) map non-reusable
ibm,slw-image@1ffda00000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffde00000..0x0000001ffdefffff (1024 KiB) map non-reusable
ibm,slw-image@1ffde00000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffe200000..0x0000001ffe2fffff (1024 KiB) map non-reusable
ibm,slw-image@1ffe200000
[ 0.000000] [ T0] OF: reserved mem:
0x0000001ffe600000..0x0000001ffe6fffff (1024 KiB) map non-reusable
ibm,slw-image@1ffe600000
[ 0.000000] [ T0] Found initrd at
0xc000000006a40000:0xc00000000815ae9e
[ 0.000000] [ T0] Hardware name: 8247-22L POWER8E (raw) 0x4b0201
opal:skiboot-v5.4.12 PowerNV
[ 0.000000] [ T0] printk: legacy bootconsole [udbg0] enabled
[ 0.000000] [ T0] CPU maps initialized for 8 threads per core
[ 0.000000] [ T0] (thread shift is 3)But I my opal version 5.4.12.
Thanks for reporting the issue, will have an look at it.
[ 0.000000] [ T0] Allocated 4608 bytes for 160 pacas
[ 0.000000] [ T0]
-----------------------------------------------------
.......
[ 37.407674] [ T900] audit: type=1130 audit(1778043621.931:10):
pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=lvm2-monitor
comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=?
terminal=? res=success'
[ 37.413015] [ T900] audit: type=1130 audit(1778043621.937:11):
pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=systemd-sysctl
comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=?
terminal=? res=success'
[ 38.448156] [ T2286] powernv_rng: Registered powernv hwrng.
[ 38.575227] [ T2264] tg3 0005:09:00.1 enP5p9s0f1: renamed from eth1
[ 38.582176] [ T2223] tg3 0005:09:00.2 enP5p9s0f2: renamed from eth2
........
////cpuinfo output
processor : 159
cpu : POWER8E (raw), altivec supported
clock : 2061.000000MHz
revision : 2.1 (pvr 004b 0201)
timebase : 512000000
platform : PowerNV
model : 8247-22L
machine : PowerNV 8247-22L
firmware : OPAL
MMU : Hash
But my system opal version 5.4.12.
Thanks for reporting the issue, will have an look at it.
Maddy
>
>
> Kind regards,
>
> Paul
^ permalink raw reply
* [PATCH] crypto: ccp: sev-dev-tsm: bail out early when pdev->bus is NULL
From: Stepan Ionichev @ 2026-05-07 2:36 UTC (permalink / raw)
To: ashish.kalra
Cc: thomas.lendacky, john.allen, herbert, davem, linux-crypto,
linux-kernel, Stepan Ionichev
dsm_create() initially checks pdev->bus when computing segment_id:
u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
But the next two lines unconditionally dereference pdev->bus via
pcie_find_root_port() and especially pci_dev_id(pdev), which expands
to PCI_DEVID(dev->bus->number, dev->devfn). If pdev->bus is in fact
NULL, segment_id is initialised to 0 but the very next statement
crashes the kernel.
smatch flags this:
drivers/crypto/ccp/sev-dev-tsm.c:253 dsm_create() error: we
previously assumed 'pdev->bus' could be null (see line 251)
Make the NULL handling consistent: if pdev->bus is NULL the device
has no PCI context to work with and SEV TIO setup cannot proceed,
so return -ENODEV before any of the bus-dependent lookups. The
remaining initialisation now runs only on the path where pdev->bus
is known to be valid.
No change for callers where pdev->bus is non-NULL, which is the
only case where dsm_create() did meaningful work before this change.
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
---
drivers/crypto/ccp/sev-dev-tsm.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c
index b07ae529b..f303d8f55 100644
--- a/drivers/crypto/ccp/sev-dev-tsm.c
+++ b/drivers/crypto/ccp/sev-dev-tsm.c
@@ -248,12 +248,19 @@ static void dsm_remove(struct pci_tsm *tsm)
static int dsm_create(struct tio_dsm *dsm)
{
struct pci_dev *pdev = dsm->tsm.base_tsm.pdev;
- u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
- struct pci_dev *rootport = pcie_find_root_port(pdev);
- u16 device_id = pci_dev_id(pdev);
+ struct pci_dev *rootport;
+ u8 segment_id;
+ u16 device_id;
u16 root_port_id;
u32 lnkcap = 0;
+ if (!pdev->bus)
+ return -ENODEV;
+
+ segment_id = pci_domain_nr(pdev->bus);
+ rootport = pcie_find_root_port(pdev);
+ device_id = pci_dev_id(pdev);
+
if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP,
&lnkcap))
return -ENODEV;
--
2.43.0
^ permalink raw reply related
* [PATCH v4 9/9] crypto: atmel: Use dmaengine_prep_config_single() API
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Using new API dmaengine_prep_config_single() to simple code.
No functional change.
Tested-by: Niklas Cassel <cassel@kernel.org>
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/crypto/atmel-aes.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index b393689400b4c17294cba73fcd16567fdd6687f4..d890b5a277b9c1394d2c7912bd663ff86321099f 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -795,7 +795,6 @@ static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd,
struct dma_slave_config config;
dma_async_tx_callback callback;
struct atmel_aes_dma *dma;
- int err;
memset(&config, 0, sizeof(config));
config.src_addr_width = addr_width;
@@ -820,12 +819,9 @@ static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd,
return -EINVAL;
}
- err = dmaengine_slave_config(dma->chan, &config);
- if (err)
- return err;
-
- desc = dmaengine_prep_slave_sg(dma->chan, dma->sg, dma->sg_len, dir,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ desc = dmaengine_prep_config_sg(dma->chan, dma->sg, dma->sg_len, dir,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ &config);
if (!desc)
return -ENOMEM;
--
2.43.0
^ permalink raw reply related
* [PATCH v4 8/9] PCI: epf-mhi: Use dmaengine_prep_config_single() to simplify code
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Use dmaengine_prep_config_single() to simplify
pci_epf_mhi_edma_read[_sync]() and pci_epf_mhi_edma_write[_sync]().
No functional change.
Tested-by: Niklas Cassel <cassel@kernel.org>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Keep mutex lock because sync with other function.
---
drivers/pci/endpoint/functions/pci-epf-mhi.c | 52 +++++++++-------------------
1 file changed, 16 insertions(+), 36 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c
index 7f5326925ed54abf4ae75c465dfe0a9bab37ce40..c3e3b58fb86cd75e175b69ca45530610c500b99e 100644
--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c
+++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c
@@ -328,12 +328,6 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl,
config.direction = DMA_DEV_TO_MEM;
config.src_addr = buf_info->host_addr;
- ret = dmaengine_slave_config(chan, &config);
- if (ret) {
- dev_err(dev, "Failed to configure DMA channel\n");
- goto err_unlock;
- }
-
dst_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
DMA_FROM_DEVICE);
ret = dma_mapping_error(dma_dev, dst_addr);
@@ -342,9 +336,10 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl,
goto err_unlock;
}
- desc = dmaengine_prep_slave_single(chan, dst_addr, buf_info->size,
- DMA_DEV_TO_MEM,
- DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+ desc = dmaengine_prep_config_single(chan, dst_addr, buf_info->size,
+ DMA_DEV_TO_MEM,
+ DMA_CTRL_ACK | DMA_PREP_INTERRUPT,
+ &config);
if (!desc) {
dev_err(dev, "Failed to prepare DMA\n");
ret = -EIO;
@@ -401,12 +396,6 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl,
config.direction = DMA_MEM_TO_DEV;
config.dst_addr = buf_info->host_addr;
- ret = dmaengine_slave_config(chan, &config);
- if (ret) {
- dev_err(dev, "Failed to configure DMA channel\n");
- goto err_unlock;
- }
-
src_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
DMA_TO_DEVICE);
ret = dma_mapping_error(dma_dev, src_addr);
@@ -415,9 +404,10 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl,
goto err_unlock;
}
- desc = dmaengine_prep_slave_single(chan, src_addr, buf_info->size,
- DMA_MEM_TO_DEV,
- DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+ desc = dmaengine_prep_config_single(chan, src_addr, buf_info->size,
+ DMA_MEM_TO_DEV,
+ DMA_CTRL_ACK | DMA_PREP_INTERRUPT,
+ &config);
if (!desc) {
dev_err(dev, "Failed to prepare DMA\n");
ret = -EIO;
@@ -506,12 +496,6 @@ static int pci_epf_mhi_edma_read_async(struct mhi_ep_cntrl *mhi_cntrl,
config.direction = DMA_DEV_TO_MEM;
config.src_addr = buf_info->host_addr;
- ret = dmaengine_slave_config(chan, &config);
- if (ret) {
- dev_err(dev, "Failed to configure DMA channel\n");
- goto err_unlock;
- }
-
dst_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
DMA_FROM_DEVICE);
ret = dma_mapping_error(dma_dev, dst_addr);
@@ -520,9 +504,10 @@ static int pci_epf_mhi_edma_read_async(struct mhi_ep_cntrl *mhi_cntrl,
goto err_unlock;
}
- desc = dmaengine_prep_slave_single(chan, dst_addr, buf_info->size,
- DMA_DEV_TO_MEM,
- DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+ desc = dmaengine_prep_config_single(chan, dst_addr, buf_info->size,
+ DMA_DEV_TO_MEM,
+ DMA_CTRL_ACK | DMA_PREP_INTERRUPT,
+ &config);
if (!desc) {
dev_err(dev, "Failed to prepare DMA\n");
ret = -EIO;
@@ -585,12 +570,6 @@ static int pci_epf_mhi_edma_write_async(struct mhi_ep_cntrl *mhi_cntrl,
config.direction = DMA_MEM_TO_DEV;
config.dst_addr = buf_info->host_addr;
- ret = dmaengine_slave_config(chan, &config);
- if (ret) {
- dev_err(dev, "Failed to configure DMA channel\n");
- goto err_unlock;
- }
-
src_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
DMA_TO_DEVICE);
ret = dma_mapping_error(dma_dev, src_addr);
@@ -599,9 +578,10 @@ static int pci_epf_mhi_edma_write_async(struct mhi_ep_cntrl *mhi_cntrl,
goto err_unlock;
}
- desc = dmaengine_prep_slave_single(chan, src_addr, buf_info->size,
- DMA_MEM_TO_DEV,
- DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+ desc = dmaengine_prep_config_single(chan, src_addr, buf_info->size,
+ DMA_MEM_TO_DEV,
+ DMA_CTRL_ACK | DMA_PREP_INTERRUPT,
+ &config);
if (!desc) {
dev_err(dev, "Failed to prepare DMA\n");
ret = -EIO;
--
2.43.0
^ permalink raw reply related
* [PATCH v4 7/9] nvmet: pci-epf: Use dmaengine_prep_config_single_safe() API
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Use the new dmaengine_prep_config_single_safe() API to combine the
configuration and descriptor preparation into a single call.
Since dmaengine_prep_config_single_safe() performs the configuration and
preparation atomically and the mutex can be removed.
Tested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
drivers/nvme/target/pci-epf.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
index 2afe8f4d0e46104a1b3c98db3905cf33e8c9e011..04d8f48d6950349ca97d2dbeae4e38e4714ad0d4 100644
--- a/drivers/nvme/target/pci-epf.c
+++ b/drivers/nvme/target/pci-epf.c
@@ -388,22 +388,15 @@ static int nvmet_pci_epf_dma_transfer(struct nvmet_pci_epf *nvme_epf,
return -EINVAL;
}
- mutex_lock(lock);
-
dma_dev = dmaengine_get_dma_device(chan);
dma_addr = dma_map_single(dma_dev, seg->buf, seg->length, dir);
ret = dma_mapping_error(dma_dev, dma_addr);
if (ret)
- goto unlock;
-
- ret = dmaengine_slave_config(chan, &sconf);
- if (ret) {
- dev_err(dev, "Failed to configure DMA channel\n");
- goto unmap;
- }
+ return ret;
- desc = dmaengine_prep_slave_single(chan, dma_addr, seg->length,
- sconf.direction, DMA_CTRL_ACK);
+ desc = dmaengine_prep_config_single_safe(chan, dma_addr, seg->length,
+ sconf.direction,
+ DMA_CTRL_ACK, &sconf);
if (!desc) {
dev_err(dev, "Failed to prepare DMA\n");
ret = -EIO;
@@ -426,9 +419,6 @@ static int nvmet_pci_epf_dma_transfer(struct nvmet_pci_epf *nvme_epf,
unmap:
dma_unmap_single(dma_dev, dma_addr, seg->length, dir);
-unlock:
- mutex_unlock(lock);
-
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v4 6/9] nvmet: pci-epf: Remove unnecessary dmaengine_terminate_sync() on each DMA transfer
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li,
Damien Le Moal
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
dmaengine_terminate_sync() cancels all pending requests. Calling it for
every DMA transfer is unnecessary and counterproductive. This function is
generally intended for cleanup paths such as module removal, device close,
or unbind operations.
Remove the redundant calls for success path and keep it only at error path.
Tested-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
This one also fix stress test failure after remove mutex and use new API
dmaengine_prep_slave_sg_config().
---
drivers/nvme/target/pci-epf.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
index 4e9db96ebfecd796244e5dc67c23e1abb1a14974..2afe8f4d0e46104a1b3c98db3905cf33e8c9e011 100644
--- a/drivers/nvme/target/pci-epf.c
+++ b/drivers/nvme/target/pci-epf.c
@@ -420,10 +420,9 @@ static int nvmet_pci_epf_dma_transfer(struct nvmet_pci_epf *nvme_epf,
if (dma_sync_wait(chan, cookie) != DMA_COMPLETE) {
dev_err(dev, "DMA transfer failed\n");
ret = -EIO;
+ dmaengine_terminate_sync(chan);
}
- dmaengine_terminate_sync(chan);
-
unmap:
dma_unmap_single(dma_dev, dma_addr, seg->length, dir);
--
2.43.0
^ permalink raw reply related
* [PATCH v4 5/9] dmaengine: dw-edma: Pass dma_slave_config to dw_edma_device_transfer()
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Pass dma_slave_config to dw_edma_device_transfer() to support atomic
configuration and descriptor preparation when a non-NULL config is
provided to device_prep_config_sg().
Tested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change in v3
- rewrite dw_edma_device_slave_config() according to Damien's suggestion.
---
drivers/dma/dw-edma/dw-edma-core.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index f7f58b0010e26b529ffb7382d5b166a703587c71..ec6f6b1e482568a27ebe90852d5679672b24a1e9 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -267,6 +267,20 @@ static int dw_edma_device_config(struct dma_chan *dchan,
return 0;
}
+static struct dma_slave_config *
+dw_edma_device_get_config(struct dma_chan *dchan,
+ struct dma_slave_config *config)
+{
+ struct dw_edma_chan *chan;
+
+ if (config)
+ return config;
+
+ chan = dchan2dw_edma_chan(dchan);
+
+ return &chan->config;
+}
+
static int dw_edma_device_pause(struct dma_chan *dchan)
{
struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
@@ -385,7 +399,8 @@ dw_edma_device_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
}
static struct dma_async_tx_descriptor *
-dw_edma_device_transfer(struct dw_edma_transfer *xfer)
+dw_edma_device_transfer(struct dw_edma_transfer *xfer,
+ struct dma_slave_config *config)
{
struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan);
enum dma_transfer_direction dir = xfer->direction;
@@ -472,8 +487,8 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
src_addr = xfer->xfer.il->src_start;
dst_addr = xfer->xfer.il->dst_start;
} else {
- src_addr = chan->config.src_addr;
- dst_addr = chan->config.dst_addr;
+ src_addr = config->src_addr;
+ dst_addr = config->dst_addr;
}
if (dir == DMA_DEV_TO_MEM)
@@ -595,7 +610,7 @@ dw_edma_device_prep_config_sg(struct dma_chan *dchan, struct scatterlist *sgl,
if (config)
dw_edma_device_config(dchan, config);
- return dw_edma_device_transfer(&xfer);
+ return dw_edma_device_transfer(&xfer, dw_edma_device_get_config(dchan, config));
}
static struct dma_async_tx_descriptor *
@@ -614,7 +629,7 @@ dw_edma_device_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t paddr,
xfer.flags = flags;
xfer.type = EDMA_XFER_CYCLIC;
- return dw_edma_device_transfer(&xfer);
+ return dw_edma_device_transfer(&xfer, dw_edma_device_get_config(dchan, NULL));
}
static struct dma_async_tx_descriptor *
@@ -630,7 +645,7 @@ dw_edma_device_prep_interleaved_dma(struct dma_chan *dchan,
xfer.flags = flags;
xfer.type = EDMA_XFER_INTERLEAVED;
- return dw_edma_device_transfer(&xfer);
+ return dw_edma_device_transfer(&xfer, dw_edma_device_get_config(dchan, NULL));
}
static void dw_hdma_set_callback_result(struct virt_dma_desc *vd,
--
2.43.0
^ permalink raw reply related
* [PATCH v4 4/9] dmaengine: dw-edma: Use new .device_prep_config_sg() callback
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li,
Damien Le Moal
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Use the new .device_prep_config_sg() callback to combine configuration and
descriptor preparation.
No functional changes.
Tested-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change in v4
- drop context in callback.
change in v3
- add Damien Le Moal review tag
---
drivers/dma/dw-edma/dw-edma-core.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index c2feb3adc79fa94b016913443305b9fae9deef12..f7f58b0010e26b529ffb7382d5b166a703587c71 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -577,10 +577,11 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
}
static struct dma_async_tx_descriptor *
-dw_edma_device_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
- unsigned int len,
- enum dma_transfer_direction direction,
- unsigned long flags, void *context)
+dw_edma_device_prep_config_sg(struct dma_chan *dchan, struct scatterlist *sgl,
+ unsigned int len,
+ enum dma_transfer_direction direction,
+ unsigned long flags,
+ struct dma_slave_config *config)
{
struct dw_edma_transfer xfer;
@@ -591,6 +592,9 @@ dw_edma_device_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
xfer.flags = flags;
xfer.type = EDMA_XFER_SCATTER_GATHER;
+ if (config)
+ dw_edma_device_config(dchan, config);
+
return dw_edma_device_transfer(&xfer);
}
@@ -970,7 +974,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
dma->device_terminate_all = dw_edma_device_terminate_all;
dma->device_issue_pending = dw_edma_device_issue_pending;
dma->device_tx_status = dw_edma_device_tx_status;
- dma->device_prep_slave_sg = dw_edma_device_prep_slave_sg;
+ dma->device_prep_config_sg = dw_edma_device_prep_config_sg;
dma->device_prep_dma_cyclic = dw_edma_device_prep_dma_cyclic;
dma->device_prep_interleaved_dma = dw_edma_device_prep_interleaved_dma;
--
2.43.0
^ permalink raw reply related
* [PATCH v4 3/9] PCI: endpoint: pci-epf-test: Use dmaenigne_prep_config_single() to simplify code
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li,
Damien Le Moal
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Use dmaenigne_prep_config_single() to simplify code.
No functional change.
Tested-by: Niklas Cassel <cassel@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change in v3
- add Damien Le Moal review tag
---
drivers/pci/endpoint/functions/pci-epf-test.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 591d301fa89d89addf5df16e775e80460b689589..0f5cf2d7951088af3801ea1cc240b2ea8627eed5 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -182,12 +182,8 @@ static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test,
else
sconf.src_addr = dma_remote;
- if (dmaengine_slave_config(chan, &sconf)) {
- dev_err(dev, "DMA slave config fail\n");
- return -EIO;
- }
- tx = dmaengine_prep_slave_single(chan, dma_local, len, dir,
- flags);
+ tx = dmaengine_prep_config_single(chan, dma_local, len,
+ dir, flags, &sconf);
} else {
tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len,
flags);
--
2.43.0
^ permalink raw reply related
* [PATCH v4 2/9] dmaengine: Add safe API to combine configuration and preparation
From: Frank Li @ 2026-05-06 20:44 UTC (permalink / raw)
To: Vinod Koul, Manivannan Sadhasivam, Krzysztof Wilczyński,
Kishon Vijay Abraham I, Bjorn Helgaas, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Herbert Xu, David S. Miller,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Koichiro Den,
Niklas Cassel
Cc: dmaengine, linux-kernel, linux-pci, linux-nvme, mhi,
linux-arm-msm, linux-crypto, linux-arm-kernel, imx, Frank Li
In-Reply-To: <20260506-dma_prep_config-v4-0-85b3d22babff@nxp.com>
Introduce dmaengine_prep_config_single_safe() and
dmaengine_prep_config_sg_safe() to provide a reentrant-safe way to
combine slave configuration and transfer preparation.
Drivers may implement the new device_prep_config_sg() callback to perform
both steps atomically. If the callback is not provided, the helpers fall
back to calling dmaengine_slave_config() followed by
dmaengine_prep_slave_sg() under per-channel mutex protection.
Tested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
chagne in v4
- use spinlock() to protect config() and prep()
change in v3
- new patch
---
drivers/dma/dmaengine.c | 2 ++
include/linux/dmaengine.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 405bd2fbb4a3b94fd0bf44526f656f6a19feaad0..ba29e60160c1a0148793bb299849bccfebb6d32b 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1099,6 +1099,8 @@ static int __dma_async_device_channel_register(struct dma_device *device,
chan->dev->device.parent = device->dev;
chan->dev->chan = chan;
chan->dev->dev_id = device->dev_id;
+ spin_lock_init(&chan->lock);
+
if (!name)
dev_set_name(&chan->dev->device, "dma%dchan%d", device->dev_id, chan->chan_id);
else
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index defa377d2ef54d94e6337cdfa7826a091295535e..23728f3d60804e49cd4cbbd3a513c4936eed5836 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -322,6 +322,8 @@ struct dma_router {
* @slave: ptr to the device using this channel
* @cookie: last cookie value returned to client
* @completed_cookie: last completed cookie for this channel
+ * @lock: protect between config and prepare transfer when driver have not
+ * implemented callback device_prep_config_sg().
* @chan_id: channel ID for sysfs
* @dev: class device for sysfs
* @name: backlink name for sysfs
@@ -341,6 +343,12 @@ struct dma_chan {
dma_cookie_t cookie;
dma_cookie_t completed_cookie;
+ /*
+ * protect between config and prepare transfer because *_prep() may be
+ * called from complete callback, which is in GFP_NOSLEEP context.
+ */
+ spinlock_t lock; /* protect between config and prepare transfer since */
+
/* sysfs */
int chan_id;
struct dma_chan_dev *dev;
@@ -1068,6 +1076,56 @@ dmaengine_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
return dmaengine_prep_config_sg(chan, sgl, sg_len, dir, flags, NULL);
}
+/*
+ * dmaengine_prep_config_single(sg)_safe() is re-entrant version.
+ *
+ * The unsafe variant (without the _safe suffix) falls back to calling
+ * dmaengine_slave_config() and dmaengine_prep_slave_sg() separately.
+ * In this case, additional locking may be required, depending on the
+ * DMA consumer's usage.
+ *
+ * If dmaengine driver have not implemented call back device_prep_config_sg()
+ * safe version use per-channel spinlock to protect call dmaengine_slave_config()
+ * and dmaengine_prep_slave_sg().
+ */
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_config_sg_safe(struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len,
+ enum dma_transfer_direction dir,
+ unsigned long flags,
+ struct dma_slave_config *config)
+{
+ struct dma_async_tx_descriptor *tx;
+
+ if (!chan || !chan->device)
+ return NULL;
+
+ if (!chan->device->device_prep_config_sg)
+ spin_lock(&chan->lock);
+
+ tx = dmaengine_prep_config_sg(chan, sgl, sg_len, dir, flags, config);
+
+ if (!chan->device->device_prep_config_sg)
+ spin_unlock(&chan->lock);
+
+ return tx;
+}
+
+static inline struct dma_async_tx_descriptor *
+dmaengine_prep_config_single_safe(struct dma_chan *chan, dma_addr_t buf,
+ size_t len, enum dma_transfer_direction dir,
+ unsigned long flags,
+ struct dma_slave_config *config)
+{
+ struct scatterlist sg;
+
+ sg_init_table(&sg, 1);
+ sg_dma_address(&sg) = buf;
+ sg_dma_len(&sg) = len;
+
+ return dmaengine_prep_config_sg_safe(chan, &sg, 1, dir, flags, config);
+}
+
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct rio_dma_ext;
static inline struct dma_async_tx_descriptor *dmaengine_prep_rio_sg(
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox