Skip to content

Commit 75fc05a

Browse files
Harsh Jaingregkh
Harsh Jain
authored andcommitted
crypto: chelsio - Fix memory corruption in DMA Mapped buffers.
commit add92a8 upstream. Update PCI Id in "cpl_rx_phys_dsgl" header. In case pci_chan_id and tx_chan_id are not derived from same queue, H/W can send request completion indication before completing DMA Transfer. Herbert, It would be good if fix can be merge to stable tree. For 4.14 kernel, It requires some update to avoid mege conficts. Cc: <[email protected]> Signed-off-by: Harsh Jain <[email protected]> Signed-off-by: Herbert Xu <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b5dcd4a commit 75fc05a

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

drivers/crypto/chelsio/chcr_algo.c

+27-14
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ static inline int is_hmac(struct crypto_tfm *tfm)
384384

385385
static void write_phys_cpl(struct cpl_rx_phys_dsgl *phys_cpl,
386386
struct scatterlist *sg,
387-
struct phys_sge_parm *sg_param)
387+
struct phys_sge_parm *sg_param,
388+
int pci_chan_id)
388389
{
389390
struct phys_sge_pairs *to;
390391
unsigned int len = 0, left_size = sg_param->obsize;
@@ -402,6 +403,7 @@ static void write_phys_cpl(struct cpl_rx_phys_dsgl *phys_cpl,
402403
phys_cpl->rss_hdr_int.opcode = CPL_RX_PHYS_ADDR;
403404
phys_cpl->rss_hdr_int.qid = htons(sg_param->qid);
404405
phys_cpl->rss_hdr_int.hash_val = 0;
406+
phys_cpl->rss_hdr_int.channel = pci_chan_id;
405407
to = (struct phys_sge_pairs *)((unsigned char *)phys_cpl +
406408
sizeof(struct cpl_rx_phys_dsgl));
407409
for (i = 0; nents && left_size; to++) {
@@ -418,7 +420,8 @@ static void write_phys_cpl(struct cpl_rx_phys_dsgl *phys_cpl,
418420
static inline int map_writesg_phys_cpl(struct device *dev,
419421
struct cpl_rx_phys_dsgl *phys_cpl,
420422
struct scatterlist *sg,
421-
struct phys_sge_parm *sg_param)
423+
struct phys_sge_parm *sg_param,
424+
int pci_chan_id)
422425
{
423426
if (!sg || !sg_param->nents)
424427
return -EINVAL;
@@ -428,7 +431,7 @@ static inline int map_writesg_phys_cpl(struct device *dev,
428431
pr_err("CHCR : DMA mapping failed\n");
429432
return -EINVAL;
430433
}
431-
write_phys_cpl(phys_cpl, sg, sg_param);
434+
write_phys_cpl(phys_cpl, sg, sg_param, pci_chan_id);
432435
return 0;
433436
}
434437

@@ -608,7 +611,7 @@ static inline void create_wreq(struct chcr_context *ctx,
608611
is_iv ? iv_loc : IV_NOP, !!lcb,
609612
ctx->tx_qidx);
610613

611-
chcr_req->ulptx.cmd_dest = FILL_ULPTX_CMD_DEST(ctx->dev->tx_channel_id,
614+
chcr_req->ulptx.cmd_dest = FILL_ULPTX_CMD_DEST(ctx->tx_chan_id,
612615
qid);
613616
chcr_req->ulptx.len = htonl((DIV_ROUND_UP((calc_tx_flits_ofld(skb) * 8),
614617
16) - ((sizeof(chcr_req->wreq)) >> 4)));
@@ -698,7 +701,8 @@ static struct sk_buff *create_cipher_wr(struct cipher_wr_param *wrparam)
698701
sg_param.obsize = wrparam->bytes;
699702
sg_param.qid = wrparam->qid;
700703
error = map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl,
701-
reqctx->dst, &sg_param);
704+
reqctx->dst, &sg_param,
705+
ctx->pci_chan_id);
702706
if (error)
703707
goto map_fail1;
704708

@@ -1228,16 +1232,23 @@ static int chcr_device_init(struct chcr_context *ctx)
12281232
adap->vres.ncrypto_fc);
12291233
rxq_perchan = u_ctx->lldi.nrxq / u_ctx->lldi.nchan;
12301234
txq_perchan = ntxq / u_ctx->lldi.nchan;
1231-
rxq_idx = ctx->dev->tx_channel_id * rxq_perchan;
1232-
rxq_idx += id % rxq_perchan;
1233-
txq_idx = ctx->dev->tx_channel_id * txq_perchan;
1234-
txq_idx += id % txq_perchan;
12351235
spin_lock(&ctx->dev->lock_chcr_dev);
1236-
ctx->rx_qidx = rxq_idx;
1237-
ctx->tx_qidx = txq_idx;
1236+
ctx->tx_chan_id = ctx->dev->tx_channel_id;
12381237
ctx->dev->tx_channel_id = !ctx->dev->tx_channel_id;
12391238
ctx->dev->rx_channel_id = 0;
12401239
spin_unlock(&ctx->dev->lock_chcr_dev);
1240+
rxq_idx = ctx->tx_chan_id * rxq_perchan;
1241+
rxq_idx += id % rxq_perchan;
1242+
txq_idx = ctx->tx_chan_id * txq_perchan;
1243+
txq_idx += id % txq_perchan;
1244+
ctx->rx_qidx = rxq_idx;
1245+
ctx->tx_qidx = txq_idx;
1246+
/* Channel Id used by SGE to forward packet to Host.
1247+
* Same value should be used in cpl_fw6_pld RSS_CH field
1248+
* by FW. Driver programs PCI channel ID to be used in fw
1249+
* at the time of queue allocation with value "pi->tx_chan"
1250+
*/
1251+
ctx->pci_chan_id = txq_idx / txq_perchan;
12411252
}
12421253
out:
12431254
return err;
@@ -2066,7 +2077,8 @@ static struct sk_buff *create_authenc_wr(struct aead_request *req,
20662077
sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
20672078
sg_param.qid = qid;
20682079
error = map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl,
2069-
reqctx->dst, &sg_param);
2080+
reqctx->dst, &sg_param,
2081+
ctx->pci_chan_id);
20702082
if (error)
20712083
goto dstmap_fail;
20722084

@@ -2389,7 +2401,7 @@ static struct sk_buff *create_aead_ccm_wr(struct aead_request *req,
23892401
sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
23902402
sg_param.qid = qid;
23912403
error = map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl,
2392-
reqctx->dst, &sg_param);
2404+
reqctx->dst, &sg_param, ctx->pci_chan_id);
23932405
if (error)
23942406
goto dstmap_fail;
23952407

@@ -2545,7 +2557,8 @@ static struct sk_buff *create_gcm_wr(struct aead_request *req,
25452557
sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
25462558
sg_param.qid = qid;
25472559
error = map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl,
2548-
reqctx->dst, &sg_param);
2560+
reqctx->dst, &sg_param,
2561+
ctx->pci_chan_id);
25492562
if (error)
25502563
goto dstmap_fail;
25512564

drivers/crypto/chelsio/chcr_crypto.h

+2
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ struct chcr_context {
222222
struct chcr_dev *dev;
223223
unsigned char tx_qidx;
224224
unsigned char rx_qidx;
225+
unsigned char tx_chan_id;
226+
unsigned char pci_chan_id;
225227
struct __crypto_ctx crypto_ctx[0];
226228
};
227229

0 commit comments

Comments
 (0)