- This patch adds kmemcache to nx_driver in replace the use of spinlocks in nx. - Adds a copy function that handles with the current context as a copy of the context in crypto API. Signed-off-by: Leonidas Da Silva Barbosa <leosilva@xxxxxxxxxxxxxxxxxx> --- drivers/crypto/nx/nx.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- drivers/crypto/nx/nx.h | 8 +++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c index 5533fe3..15fe87f 100644 --- a/drivers/crypto/nx/nx.c +++ b/drivers/crypto/nx/nx.c @@ -255,7 +255,6 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, */ void nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function) { - spin_lock_init(&nx_ctx->lock); memset(nx_ctx->kmem, 0, nx_ctx->kmem_len); nx_ctx->csbcpb->csb.valid |= NX_CSB_VALID_BIT; @@ -633,6 +632,7 @@ void nx_crypto_ctx_exit(struct crypto_tfm *tfm) static int nx_probe(struct vio_dev *viodev, const struct vio_device_id *id) { + int rc; dev_dbg(&viodev->dev, "driver probed: %s resource id: 0x%x\n", viodev->name, viodev->resource_id); @@ -646,7 +646,17 @@ static int nx_probe(struct vio_dev *viodev, const struct vio_device_id *id) nx_of_init(&viodev->dev, &nx_driver.of); - return nx_register_algs(); + nx_driver.slab = kmem_cache_create("nx_slab", 5 * NX_PAGE_SIZE, + 0, 0, NULL); + if (!nx_driver.slab) { + dev_err(&viodev->dev, "%s: Failed to allocate slab\n", __func__); + return -ENOMEM; + } + + rc = nx_register_algs(); + if (rc) + kmem_cache_destroy(nx_driver.slab); + return rc; } static int nx_remove(struct vio_dev *viodev) @@ -668,11 +678,42 @@ static int nx_remove(struct vio_dev *viodev) crypto_unregister_shash(&nx_shash_sha256_alg); crypto_unregister_shash(&nx_shash_sha512_alg); crypto_unregister_shash(&nx_shash_aes_xcbc_alg); + kmem_cache_destroy(nx_driver.slab); } return 0; } +int nx_copy_ctx(struct nx_crypto_ctx *dst, + const struct nx_crypto_ctx *src) +{ + memcpy(dst, src, sizeof(*src)); + dst->kmem = kmem_cache_alloc(nx_driver.slab, GFP_ATOMIC); + if (!dst->kmem) + return -ENOMEM; + + /* the csbcpb and scatterlist must be 4k aligned pages */ + dst->csbcpb = (struct nx_csbcpb *)(round_up((u64) dst->kmem, + (u64)NX_PAGE_SIZE)); + dst->in_sg = (struct nx_sg *)((u8 *) dst->csbcpb + NX_PAGE_SIZE); + dst->out_sg = (struct nx_sg *)((u8 *) dst->in_sg + NX_PAGE_SIZE); + dst->op.csbcpb = __pa(dst->csbcpb); + dst->op.in = __pa(dst->in_sg); + dst->op.out =__pa(dst->out_sg); + + if (src->csbcpb->cpb.hdr.mode == NX_MODE_AES_GCM || + src->csbcpb->cpb.hdr.mode == NX_MODE_AES_CCM) { + dst->csbcpb_aead = + (struct nx_csbcpb *)((u8 *)src->out_sg + NX_PAGE_SIZE); + dst->op_aead.csbcpb = __pa(dst->csbcpb_aead); + dst->op_aead.in = __pa(dst->in_sg); + dst->op_aead.out = __pa(dst->out_sg); + + memcpy(dst->csbcpb_aead, src->csbcpb_aead, sizeof(struct nx_csbcpb)); + } + memcpy(dst->csbcpb, src->csbcpb, sizeof(struct nx_csbcpb)); + return 0; +} /* module wide initialization/cleanup */ static int __init nx_init(void) diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h index befda07..af15510 100644 --- a/drivers/crypto/nx/nx.h +++ b/drivers/crypto/nx/nx.h @@ -6,14 +6,15 @@ #define NX_STRING "IBM Power7+ Nest Accelerator Crypto Driver" #define NX_VERSION "1.0" +#include <linux/slab.h> + static const char nx_driver_string[] = NX_STRING; static const char nx_driver_version[] = NX_VERSION; /* a scatterlist in the format PHYP is expecting */ struct nx_sg { u64 addr; - u32 rsvd; - u32 len; + u64 len; } __attribute((packed)); #define NX_PAGE_SIZE (4096) @@ -87,6 +88,7 @@ struct nx_crypto_driver { struct vio_dev *viodev; struct vio_driver viodriver; struct nx_debugfs dfs; + struct kmem_cache *slab; }; #define NX_GCM4106_NONCE_LEN (4) @@ -117,7 +119,6 @@ struct nx_ctr_priv { }; struct nx_crypto_ctx { - spinlock_t lock; /* synchronize access to the context */ void *kmem; /* unaligned, kmalloc'd buffer */ size_t kmem_len; /* length of kmem */ struct nx_csbcpb *csbcpb; /* aligned page given to phyp @ hcall time */ @@ -160,6 +161,7 @@ int nx_build_sg_lists(struct nx_crypto_ctx *, struct blkcipher_desc *, struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, struct scatterlist *, unsigned int, unsigned int); +int nx_copy_ctx(struct nx_crypto_ctx *, const struct nx_crypto_ctx *); #ifdef CONFIG_DEBUG_FS #define NX_DEBUGFS_INIT(drv) nx_debugfs_init(drv) -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html