From fa9a9a084a2153095d0433188be232b0127ab23c Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Thu, 2 Jul 2015 15:38:48 -0700 Subject: crypto: nx - nx842_OF_upd_status should return ENODEV if device is not 'okay' The current documention mentions explicitly that EINVAL should be returned if the device is not available, but nx842_OF_upd_status() always returns 0. However, nx842_probe() specifically checks for non-ENODEV returns from nx842_of_upd() (which in turn calls nx842_OF_upd_status()) and emits an extra error in that case. It seems like the proper return code of a disabled device is ENODEV. Signed-off-by: Nishanth Aravamudan Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index 3040a6091bf2..819c23c546e3 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -556,7 +556,7 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata) * * Returns: * 0 - Device is available - * -EINVAL - Device is not available + * -ENODEV - Device is not available */ static int nx842_OF_upd_status(struct nx842_devdata *devdata, struct property *prop) { @@ -569,6 +569,7 @@ static int nx842_OF_upd_status(struct nx842_devdata *devdata, dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n", __func__, status); devdata->status = UNAVAILABLE; + ret = -ENODEV; } return ret; -- cgit v1.2.3 From ec13bcbe07a202c32ea74927e27479aa4d19d1b1 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Thu, 2 Jul 2015 15:39:21 -0700 Subject: crypto: nx - rename nx842_{init, exit} to nx842_pseries_{init, exit} While there is no technical reason that both nx-842.c and nx-842-pseries.c can have the same name for the init/exit functions, it is a bit confusing with initcall_debug. Rename the pseries specific functions appropriately Signed-off-by: Nishanth Aravamudan Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index 819c23c546e3..e17f4d2e96e0 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -1080,7 +1080,7 @@ static struct vio_driver nx842_vio_driver = { .id_table = nx842_vio_driver_ids, }; -static int __init nx842_init(void) +static int __init nx842_pseries_init(void) { struct nx842_devdata *new_devdata; int ret; @@ -1116,9 +1116,9 @@ static int __init nx842_init(void) return 0; } -module_init(nx842_init); +module_init(nx842_pseries_init); -static void __exit nx842_exit(void) +static void __exit nx842_pseries_exit(void) { struct nx842_devdata *old_devdata; unsigned long flags; @@ -1137,5 +1137,5 @@ static void __exit nx842_exit(void) vio_unregister_driver(&nx842_vio_driver); } -module_exit(nx842_exit); +module_exit(nx842_pseries_exit); -- cgit v1.2.3 From 7abd75bf7ac6d04e0389472cf2cd3a8bf53e4894 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Thu, 2 Jul 2015 15:40:09 -0700 Subject: crypto: nx - do not emit extra output if status is disabled If the device-tree indicates the nx-842 device's status is 'disabled', we emit two messages: nx_compress_pseries ibm,compression-v1: nx842_OF_upd_status: status 'disabled' is not 'okay'. nx_compress_pseries ibm,compression-v1: nx842_OF_upd: device disabled Given that 'disabled' is a valid state, and we are going to emit that the device is disabled, only print out a non-'okay' status if it is not 'disabled'. Signed-off-by: Nishanth Aravamudan Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index e17f4d2e96e0..b84b0ceeb46e 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -566,8 +566,14 @@ static int nx842_OF_upd_status(struct nx842_devdata *devdata, if (!strncmp(status, "okay", (size_t)prop->length)) { devdata->status = AVAILABLE; } else { - dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n", + /* + * Caller will log that the device is disabled, so only + * output if there is an unexpected status. + */ + if (strncmp(status, "disabled", (size_t)prop->length)) { + dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n", __func__, status); + } devdata->status = UNAVAILABLE; ret = -ENODEV; } -- cgit v1.2.3 From 2b93f7ee0836d1dbcfcf8560dd2a34cd51b3ff21 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 6 Jul 2015 10:06:21 -0700 Subject: crypto: nx - reduce chattiness of platform drivers While we never would successfully load on the wrong machine type, there is extra output by default regardless of machine type. For instance, on a PowerVM LPAR, we see the following: nx_compress_powernv: loading nx_compress_powernv: no coprocessors found even though those coprocessors could never be found. Signed-off-by: Nishanth Aravamudan Cc: Dan Streetman Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-crypto@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Acked-by: Michael Ellerman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-powernv.c | 10 +--------- drivers/crypto/nx/nx-842-pseries.c | 3 --- 2 files changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 33b3b0abf4ae..7e474562058d 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -594,15 +594,11 @@ static __init int nx842_powernv_init(void) BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT); BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT); - pr_info("loading\n"); - for_each_compatible_node(dn, NULL, "ibm,power-nx") nx842_powernv_probe(dn); - if (!nx842_ct) { - pr_err("no coprocessors found\n"); + if (!nx842_ct) return -ENODEV; - } if (!nx842_platform_driver_set(&nx842_powernv_driver)) { struct nx842_coproc *coproc, *n; @@ -615,8 +611,6 @@ static __init int nx842_powernv_init(void) return -EEXIST; } - pr_info("loaded\n"); - return 0; } module_init(nx842_powernv_init); @@ -631,7 +625,5 @@ static void __exit nx842_powernv_exit(void) list_del(&coproc->list); kfree(coproc); } - - pr_info("unloaded\n"); } module_exit(nx842_powernv_exit); diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index b84b0ceeb46e..d44524da6589 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -1091,8 +1091,6 @@ static int __init nx842_pseries_init(void) struct nx842_devdata *new_devdata; int ret; - pr_info("Registering IBM Power 842 compression driver\n"); - if (!of_find_compatible_node(NULL, NULL, "ibm,compression")) return -ENODEV; @@ -1129,7 +1127,6 @@ static void __exit nx842_pseries_exit(void) struct nx842_devdata *old_devdata; unsigned long flags; - pr_info("Exiting IBM Power 842 compression driver\n"); nx842_platform_driver_unset(&nx842_pseries_driver); spin_lock_irqsave(&devdata_mutex, flags); old_devdata = rcu_dereference_check(devdata, -- cgit v1.2.3 From 23ad69aafec5d3815fdbe59aea56ec4b59dcae60 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 8 Jul 2015 21:40:39 +0800 Subject: crypto: nx/842 - Fix context corruption The transform context is shared memory and must not be written to without locking. This patch adds locking to nx-842 to prevent context corruption. Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-crypto.c | 48 ++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-crypto.c b/drivers/crypto/nx/nx-842-crypto.c index d53a1dcd7b4e..3288a701c91b 100644 --- a/drivers/crypto/nx/nx-842-crypto.c +++ b/drivers/crypto/nx/nx-842-crypto.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "nx-842.h" @@ -125,6 +126,8 @@ static int update_param(struct nx842_crypto_param *p, } struct nx842_crypto_ctx { + spinlock_t lock; + u8 *wmem; u8 *sbounce, *dbounce; @@ -136,6 +139,7 @@ static int nx842_crypto_init(struct crypto_tfm *tfm) { struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm); + spin_lock_init(&ctx->lock); ctx->wmem = kmalloc(nx842_workmem_size(), GFP_KERNEL); ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); @@ -315,6 +319,8 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, DIV_ROUND_UP(p.iremain, c.maximum)); hdrsize = NX842_CRYPTO_HEADER_SIZE(groups); + spin_lock_bh(&ctx->lock); + /* skip adding header if the buffers meet all constraints */ add_header = (p.iremain % c.multiple || p.iremain < c.minimum || @@ -331,8 +337,9 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, while (p.iremain > 0) { n = hdr->groups++; + ret = -ENOSPC; if (hdr->groups > NX842_CRYPTO_GROUP_MAX) - return -ENOSPC; + goto unlock; /* header goes before first group */ h = !n && add_header ? hdrsize : 0; @@ -342,12 +349,13 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, ret = compress(ctx, &p, &hdr->group[n], &c, &ignore, h); if (ret) - return ret; + goto unlock; } if (!add_header && hdr->groups > 1) { pr_err("Internal error: No header but multiple groups\n"); - return -EINVAL; + ret = -EINVAL; + goto unlock; } /* ignore indicates the input stream needed to be padded */ @@ -358,13 +366,15 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, if (add_header) ret = nx842_crypto_add_header(hdr, dst); if (ret) - return ret; + goto unlock; *dlen = p.ototal; pr_debug("compress total slen %x dlen %x\n", slen, *dlen); - return 0; +unlock: + spin_unlock_bh(&ctx->lock); + return ret; } static int decompress(struct nx842_crypto_ctx *ctx, @@ -494,6 +504,8 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, hdr = (struct nx842_crypto_header *)src; + spin_lock_bh(&ctx->lock); + /* If it doesn't start with our header magic number, assume it's a raw * 842 compressed buffer and pass it directly to the hardware driver */ @@ -506,26 +518,31 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, ret = decompress(ctx, &p, &g, &c, 0, usehw); if (ret) - return ret; + goto unlock; *dlen = p.ototal; - return 0; + ret = 0; + goto unlock; } if (!hdr->groups) { pr_err("header has no groups\n"); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (hdr->groups > NX842_CRYPTO_GROUP_MAX) { pr_err("header has too many groups %x, max %x\n", hdr->groups, NX842_CRYPTO_GROUP_MAX); - return -EINVAL; + ret = -EINVAL; + goto unlock; } hdr_len = NX842_CRYPTO_HEADER_SIZE(hdr->groups); - if (hdr_len > slen) - return -EOVERFLOW; + if (hdr_len > slen) { + ret = -EOVERFLOW; + goto unlock; + } memcpy(&ctx->header, src, hdr_len); hdr = &ctx->header; @@ -537,14 +554,19 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, ret = decompress(ctx, &p, &hdr->group[n], &c, ignore, usehw); if (ret) - return ret; + goto unlock; } *dlen = p.ototal; pr_debug("decompress total slen %x dlen %x\n", slen, *dlen); - return 0; + ret = 0; + +unlock: + spin_unlock_bh(&ctx->lock); + + return ret; } static struct crypto_alg alg = { -- cgit v1.2.3 From c3d219495ed583a03ea10b5b30bccec398299cb7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 9 Jul 2015 07:17:31 +0800 Subject: crypto: nx - Use new IV convention This patch converts rfc4106 to the new calling convention where the IV is now part of the AD and needs to be skipped. This patch also makes use of type-safe AEAD functions where possible. Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-aes-gcm.c | 66 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c index 92c993f08213..5719638b8642 100644 --- a/drivers/crypto/nx/nx-aes-gcm.c +++ b/drivers/crypto/nx/nx-aes-gcm.c @@ -21,11 +21,9 @@ #include #include -#include #include #include #include -#include #include #include "nx_csbcpb.h" @@ -36,7 +34,7 @@ static int gcm_aes_nx_set_key(struct crypto_aead *tfm, const u8 *in_key, unsigned int key_len) { - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&tfm->base); + struct nx_crypto_ctx *nx_ctx = crypto_aead_ctx(tfm); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; struct nx_csbcpb *csbcpb_aead = nx_ctx->csbcpb_aead; @@ -75,7 +73,7 @@ static int gcm4106_aes_nx_set_key(struct crypto_aead *tfm, const u8 *in_key, unsigned int key_len) { - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&tfm->base); + struct nx_crypto_ctx *nx_ctx = crypto_aead_ctx(tfm); char *nonce = nx_ctx->priv.gcm.nonce; int rc; @@ -110,13 +108,14 @@ static int gcm4106_aes_nx_setauthsize(struct crypto_aead *tfm, static int nx_gca(struct nx_crypto_ctx *nx_ctx, struct aead_request *req, - u8 *out) + u8 *out, + unsigned int assoclen) { int rc; struct nx_csbcpb *csbcpb_aead = nx_ctx->csbcpb_aead; struct scatter_walk walk; struct nx_sg *nx_sg = nx_ctx->in_sg; - unsigned int nbytes = req->assoclen; + unsigned int nbytes = assoclen; unsigned int processed = 0, to_process; unsigned int max_sg_len; @@ -167,7 +166,7 @@ static int nx_gca(struct nx_crypto_ctx *nx_ctx, NX_CPB_FDM(csbcpb_aead) |= NX_FDM_CONTINUATION; atomic_inc(&(nx_ctx->stats->aes_ops)); - atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes)); + atomic64_add(assoclen, &(nx_ctx->stats->aes_bytes)); processed += to_process; } while (processed < nbytes); @@ -177,13 +176,15 @@ static int nx_gca(struct nx_crypto_ctx *nx_ctx, return rc; } -static int gmac(struct aead_request *req, struct blkcipher_desc *desc) +static int gmac(struct aead_request *req, struct blkcipher_desc *desc, + unsigned int assoclen) { int rc; - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); + struct nx_crypto_ctx *nx_ctx = + crypto_aead_ctx(crypto_aead_reqtfm(req)); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; struct nx_sg *nx_sg; - unsigned int nbytes = req->assoclen; + unsigned int nbytes = assoclen; unsigned int processed = 0, to_process; unsigned int max_sg_len; @@ -238,7 +239,7 @@ static int gmac(struct aead_request *req, struct blkcipher_desc *desc) NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION; atomic_inc(&(nx_ctx->stats->aes_ops)); - atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes)); + atomic64_add(assoclen, &(nx_ctx->stats->aes_bytes)); processed += to_process; } while (processed < nbytes); @@ -253,7 +254,8 @@ static int gcm_empty(struct aead_request *req, struct blkcipher_desc *desc, int enc) { int rc; - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); + struct nx_crypto_ctx *nx_ctx = + crypto_aead_ctx(crypto_aead_reqtfm(req)); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; char out[AES_BLOCK_SIZE]; struct nx_sg *in_sg, *out_sg; @@ -314,9 +316,11 @@ out: return rc; } -static int gcm_aes_nx_crypt(struct aead_request *req, int enc) +static int gcm_aes_nx_crypt(struct aead_request *req, int enc, + unsigned int assoclen) { - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); + struct nx_crypto_ctx *nx_ctx = + crypto_aead_ctx(crypto_aead_reqtfm(req)); struct nx_gcm_rctx *rctx = aead_request_ctx(req); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; struct blkcipher_desc desc; @@ -332,10 +336,10 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) *(u32 *)(desc.info + NX_GCM_CTR_OFFSET) = 1; if (nbytes == 0) { - if (req->assoclen == 0) + if (assoclen == 0) rc = gcm_empty(req, &desc, enc); else - rc = gmac(req, &desc); + rc = gmac(req, &desc, assoclen); if (rc) goto out; else @@ -343,9 +347,10 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) } /* Process associated data */ - csbcpb->cpb.aes_gcm.bit_length_aad = req->assoclen * 8; - if (req->assoclen) { - rc = nx_gca(nx_ctx, req, csbcpb->cpb.aes_gcm.in_pat_or_aad); + csbcpb->cpb.aes_gcm.bit_length_aad = assoclen * 8; + if (assoclen) { + rc = nx_gca(nx_ctx, req, csbcpb->cpb.aes_gcm.in_pat_or_aad, + assoclen); if (rc) goto out; } @@ -363,7 +368,6 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) to_process = nbytes - processed; csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8; - desc.tfm = (struct crypto_blkcipher *) req->base.tfm; rc = nx_build_sg_lists(nx_ctx, &desc, req->dst, req->src, &to_process, processed + req->assoclen, @@ -430,7 +434,7 @@ static int gcm_aes_nx_encrypt(struct aead_request *req) memcpy(iv, req->iv, 12); - return gcm_aes_nx_crypt(req, 1); + return gcm_aes_nx_crypt(req, 1, req->assoclen); } static int gcm_aes_nx_decrypt(struct aead_request *req) @@ -440,12 +444,13 @@ static int gcm_aes_nx_decrypt(struct aead_request *req) memcpy(iv, req->iv, 12); - return gcm_aes_nx_crypt(req, 0); + return gcm_aes_nx_crypt(req, 0, req->assoclen); } static int gcm4106_aes_nx_encrypt(struct aead_request *req) { - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); + struct nx_crypto_ctx *nx_ctx = + crypto_aead_ctx(crypto_aead_reqtfm(req)); struct nx_gcm_rctx *rctx = aead_request_ctx(req); char *iv = rctx->iv; char *nonce = nx_ctx->priv.gcm.nonce; @@ -453,12 +458,16 @@ static int gcm4106_aes_nx_encrypt(struct aead_request *req) memcpy(iv, nonce, NX_GCM4106_NONCE_LEN); memcpy(iv + NX_GCM4106_NONCE_LEN, req->iv, 8); - return gcm_aes_nx_crypt(req, 1); + if (req->assoclen < 8) + return -EINVAL; + + return gcm_aes_nx_crypt(req, 1, req->assoclen - 8); } static int gcm4106_aes_nx_decrypt(struct aead_request *req) { - struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); + struct nx_crypto_ctx *nx_ctx = + crypto_aead_ctx(crypto_aead_reqtfm(req)); struct nx_gcm_rctx *rctx = aead_request_ctx(req); char *iv = rctx->iv; char *nonce = nx_ctx->priv.gcm.nonce; @@ -466,7 +475,10 @@ static int gcm4106_aes_nx_decrypt(struct aead_request *req) memcpy(iv, nonce, NX_GCM4106_NONCE_LEN); memcpy(iv + NX_GCM4106_NONCE_LEN, req->iv, 8); - return gcm_aes_nx_crypt(req, 0); + if (req->assoclen < 8) + return -EINVAL; + + return gcm_aes_nx_crypt(req, 0, req->assoclen - 8); } /* tell the block cipher walk routines that this is a stream cipher by @@ -478,6 +490,7 @@ struct aead_alg nx_gcm_aes_alg = { .base = { .cra_name = "gcm(aes)", .cra_driver_name = "gcm-aes-nx", + .cra_flags = CRYPTO_ALG_AEAD_NEW, .cra_priority = 300, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct nx_crypto_ctx), @@ -496,6 +509,7 @@ struct aead_alg nx_gcm4106_aes_alg = { .base = { .cra_name = "rfc4106(gcm(aes))", .cra_driver_name = "rfc4106-gcm-aes-nx", + .cra_flags = CRYPTO_ALG_AEAD_NEW, .cra_priority = 300, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct nx_crypto_ctx), -- cgit v1.2.3 From cc81565307822a062820da294c17d9f3b6f49ecd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 14 Jul 2015 16:53:21 +0800 Subject: crypto: nx - Convert ccm to new AEAD interface This patch converts the nx ccm and 4309 implementations to the new AEAD interface. Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-aes-ccm.c | 153 +++++++++++++++++++---------------------- drivers/crypto/nx/nx.c | 21 +++--- drivers/crypto/nx/nx.h | 6 +- 3 files changed, 85 insertions(+), 95 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-aes-ccm.c b/drivers/crypto/nx/nx-aes-ccm.c index e4311ce0cd78..195c9207a98d 100644 --- a/drivers/crypto/nx/nx-aes-ccm.c +++ b/drivers/crypto/nx/nx-aes-ccm.c @@ -94,8 +94,6 @@ static int ccm_aes_nx_setauthsize(struct crypto_aead *tfm, return -EINVAL; } - crypto_aead_crt(tfm)->authsize = authsize; - return 0; } @@ -111,8 +109,6 @@ static int ccm4309_aes_nx_setauthsize(struct crypto_aead *tfm, return -EINVAL; } - crypto_aead_crt(tfm)->authsize = authsize; - return 0; } @@ -174,6 +170,7 @@ static int generate_pat(u8 *iv, struct nx_crypto_ctx *nx_ctx, unsigned int authsize, unsigned int nbytes, + unsigned int assoclen, u8 *out) { struct nx_sg *nx_insg = nx_ctx->in_sg; @@ -200,16 +197,16 @@ static int generate_pat(u8 *iv, * greater than 2^32. */ - if (!req->assoclen) { + if (!assoclen) { b0 = nx_ctx->csbcpb->cpb.aes_ccm.in_pat_or_b0; - } else if (req->assoclen <= 14) { + } else if (assoclen <= 14) { /* if associated data is 14 bytes or less, we do 1 GCM * operation on 2 AES blocks, B0 (stored in the csbcpb) and B1, * which is fed in through the source buffers here */ b0 = nx_ctx->csbcpb->cpb.aes_ccm.in_pat_or_b0; b1 = nx_ctx->priv.ccm.iauth_tag; - iauth_len = req->assoclen; - } else if (req->assoclen <= 65280) { + iauth_len = assoclen; + } else if (assoclen <= 65280) { /* if associated data is less than (2^16 - 2^8), we construct * B1 differently and feed in the associated data to a CCA * operation */ @@ -223,7 +220,7 @@ static int generate_pat(u8 *iv, } /* generate B0 */ - rc = generate_b0(iv, req->assoclen, authsize, nbytes, b0); + rc = generate_b0(iv, assoclen, authsize, nbytes, b0); if (rc) return rc; @@ -233,22 +230,22 @@ static int generate_pat(u8 *iv, */ if (b1) { memset(b1, 0, 16); - if (req->assoclen <= 65280) { - *(u16 *)b1 = (u16)req->assoclen; - scatterwalk_map_and_copy(b1 + 2, req->assoc, 0, + if (assoclen <= 65280) { + *(u16 *)b1 = assoclen; + scatterwalk_map_and_copy(b1 + 2, req->src, 0, iauth_len, SCATTERWALK_FROM_SG); } else { *(u16 *)b1 = (u16)(0xfffe); - *(u32 *)&b1[2] = (u32)req->assoclen; - scatterwalk_map_and_copy(b1 + 6, req->assoc, 0, + *(u32 *)&b1[2] = assoclen; + scatterwalk_map_and_copy(b1 + 6, req->src, 0, iauth_len, SCATTERWALK_FROM_SG); } } /* now copy any remaining AAD to scatterlist and call nx... */ - if (!req->assoclen) { + if (!assoclen) { return rc; - } else if (req->assoclen <= 14) { + } else if (assoclen <= 14) { unsigned int len = 16; nx_insg = nx_build_sg_list(nx_insg, b1, &len, nx_ctx->ap->sglen); @@ -280,7 +277,7 @@ static int generate_pat(u8 *iv, return rc; atomic_inc(&(nx_ctx->stats->aes_ops)); - atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes)); + atomic64_add(assoclen, &nx_ctx->stats->aes_bytes); } else { unsigned int processed = 0, to_process; @@ -294,15 +291,15 @@ static int generate_pat(u8 *iv, nx_ctx->ap->databytelen/NX_PAGE_SIZE); do { - to_process = min_t(u32, req->assoclen - processed, + to_process = min_t(u32, assoclen - processed, nx_ctx->ap->databytelen); nx_insg = nx_walk_and_build(nx_ctx->in_sg, nx_ctx->ap->sglen, - req->assoc, processed, + req->src, processed, &to_process); - if ((to_process + processed) < req->assoclen) { + if ((to_process + processed) < assoclen) { NX_CPB_FDM(nx_ctx->csbcpb_aead) |= NX_FDM_INTERMEDIATE; } else { @@ -328,11 +325,10 @@ static int generate_pat(u8 *iv, NX_CPB_FDM(nx_ctx->csbcpb_aead) |= NX_FDM_CONTINUATION; atomic_inc(&(nx_ctx->stats->aes_ops)); - atomic64_add(req->assoclen, - &(nx_ctx->stats->aes_bytes)); + atomic64_add(assoclen, &nx_ctx->stats->aes_bytes); processed += to_process; - } while (processed < req->assoclen); + } while (processed < assoclen); result = nx_ctx->csbcpb_aead->cpb.aes_cca.out_pat_or_b0; } @@ -343,7 +339,8 @@ static int generate_pat(u8 *iv, } static int ccm_nx_decrypt(struct aead_request *req, - struct blkcipher_desc *desc) + struct blkcipher_desc *desc, + unsigned int assoclen) { struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; @@ -360,10 +357,10 @@ static int ccm_nx_decrypt(struct aead_request *req, /* copy out the auth tag to compare with later */ scatterwalk_map_and_copy(priv->oauth_tag, - req->src, nbytes, authsize, + req->src, nbytes + req->assoclen, authsize, SCATTERWALK_FROM_SG); - rc = generate_pat(desc->info, req, nx_ctx, authsize, nbytes, + rc = generate_pat(desc->info, req, nx_ctx, authsize, nbytes, assoclen, csbcpb->cpb.aes_ccm.in_pat_or_b0); if (rc) goto out; @@ -383,8 +380,8 @@ static int ccm_nx_decrypt(struct aead_request *req, NX_CPB_FDM(nx_ctx->csbcpb) &= ~NX_FDM_ENDE_ENCRYPT; rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, - &to_process, processed, - csbcpb->cpb.aes_ccm.iv_or_ctr); + &to_process, processed + req->assoclen, + csbcpb->cpb.aes_ccm.iv_or_ctr); if (rc) goto out; @@ -420,7 +417,8 @@ out: } static int ccm_nx_encrypt(struct aead_request *req, - struct blkcipher_desc *desc) + struct blkcipher_desc *desc, + unsigned int assoclen) { struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm); struct nx_csbcpb *csbcpb = nx_ctx->csbcpb; @@ -432,7 +430,7 @@ static int ccm_nx_encrypt(struct aead_request *req, spin_lock_irqsave(&nx_ctx->lock, irq_flags); - rc = generate_pat(desc->info, req, nx_ctx, authsize, nbytes, + rc = generate_pat(desc->info, req, nx_ctx, authsize, nbytes, assoclen, csbcpb->cpb.aes_ccm.in_pat_or_b0); if (rc) goto out; @@ -451,7 +449,7 @@ static int ccm_nx_encrypt(struct aead_request *req, NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT; rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, - &to_process, processed, + &to_process, processed + req->assoclen, csbcpb->cpb.aes_ccm.iv_or_ctr); if (rc) goto out; @@ -483,7 +481,7 @@ static int ccm_nx_encrypt(struct aead_request *req, /* copy out the auth tag */ scatterwalk_map_and_copy(csbcpb->cpb.aes_ccm.out_pat_or_mac, - req->dst, nbytes, authsize, + req->dst, nbytes + req->assoclen, authsize, SCATTERWALK_TO_SG); out: @@ -503,9 +501,8 @@ static int ccm4309_aes_nx_encrypt(struct aead_request *req) memcpy(iv + 4, req->iv, 8); desc.info = iv; - desc.tfm = (struct crypto_blkcipher *)req->base.tfm; - return ccm_nx_encrypt(req, &desc); + return ccm_nx_encrypt(req, &desc, req->assoclen - 8); } static int ccm_aes_nx_encrypt(struct aead_request *req) @@ -514,13 +511,12 @@ static int ccm_aes_nx_encrypt(struct aead_request *req) int rc; desc.info = req->iv; - desc.tfm = (struct crypto_blkcipher *)req->base.tfm; rc = crypto_ccm_check_iv(desc.info); if (rc) return rc; - return ccm_nx_encrypt(req, &desc); + return ccm_nx_encrypt(req, &desc, req->assoclen); } static int ccm4309_aes_nx_decrypt(struct aead_request *req) @@ -535,9 +531,8 @@ static int ccm4309_aes_nx_decrypt(struct aead_request *req) memcpy(iv + 4, req->iv, 8); desc.info = iv; - desc.tfm = (struct crypto_blkcipher *)req->base.tfm; - return ccm_nx_decrypt(req, &desc); + return ccm_nx_decrypt(req, &desc, req->assoclen - 8); } static int ccm_aes_nx_decrypt(struct aead_request *req) @@ -546,13 +541,12 @@ static int ccm_aes_nx_decrypt(struct aead_request *req) int rc; desc.info = req->iv; - desc.tfm = (struct crypto_blkcipher *)req->base.tfm; rc = crypto_ccm_check_iv(desc.info); if (rc) return rc; - return ccm_nx_decrypt(req, &desc); + return ccm_nx_decrypt(req, &desc, req->assoclen); } /* tell the block cipher walk routines that this is a stream cipher by @@ -560,47 +554,44 @@ static int ccm_aes_nx_decrypt(struct aead_request *req) * during encrypt/decrypt doesn't solve this problem, because it calls * blkcipher_walk_done under the covers, which doesn't use walk->blocksize, * but instead uses this tfm->blocksize. */ -struct crypto_alg nx_ccm_aes_alg = { - .cra_name = "ccm(aes)", - .cra_driver_name = "ccm-aes-nx", - .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | - CRYPTO_ALG_NEED_FALLBACK, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct nx_crypto_ctx), - .cra_type = &crypto_aead_type, - .cra_module = THIS_MODULE, - .cra_init = nx_crypto_ctx_aes_ccm_init, - .cra_exit = nx_crypto_ctx_exit, - .cra_aead = { - .ivsize = AES_BLOCK_SIZE, - .maxauthsize = AES_BLOCK_SIZE, - .setkey = ccm_aes_nx_set_key, - .setauthsize = ccm_aes_nx_setauthsize, - .encrypt = ccm_aes_nx_encrypt, - .decrypt = ccm_aes_nx_decrypt, - } +struct aead_alg nx_ccm_aes_alg = { + .base = { + .cra_name = "ccm(aes)", + .cra_driver_name = "ccm-aes-nx", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK | + CRYPTO_ALG_AEAD_NEW, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct nx_crypto_ctx), + .cra_module = THIS_MODULE, + }, + .init = nx_crypto_ctx_aes_ccm_init, + .exit = nx_crypto_ctx_aead_exit, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .setkey = ccm_aes_nx_set_key, + .setauthsize = ccm_aes_nx_setauthsize, + .encrypt = ccm_aes_nx_encrypt, + .decrypt = ccm_aes_nx_decrypt, }; -struct crypto_alg nx_ccm4309_aes_alg = { - .cra_name = "rfc4309(ccm(aes))", - .cra_driver_name = "rfc4309-ccm-aes-nx", - .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | - CRYPTO_ALG_NEED_FALLBACK, - .cra_blocksize = 1, - .cra_ctxsize = sizeof(struct nx_crypto_ctx), - .cra_type = &crypto_nivaead_type, - .cra_module = THIS_MODULE, - .cra_init = nx_crypto_ctx_aes_ccm_init, - .cra_exit = nx_crypto_ctx_exit, - .cra_aead = { - .ivsize = 8, - .maxauthsize = AES_BLOCK_SIZE, - .setkey = ccm4309_aes_nx_set_key, - .setauthsize = ccm4309_aes_nx_setauthsize, - .encrypt = ccm4309_aes_nx_encrypt, - .decrypt = ccm4309_aes_nx_decrypt, - .geniv = "seqiv", - } +struct aead_alg nx_ccm4309_aes_alg = { + .base = { + .cra_name = "rfc4309(ccm(aes))", + .cra_driver_name = "rfc4309-ccm-aes-nx", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_NEED_FALLBACK | + CRYPTO_ALG_AEAD_NEW, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct nx_crypto_ctx), + .cra_module = THIS_MODULE, + }, + .init = nx_crypto_ctx_aes_ccm_init, + .exit = nx_crypto_ctx_aead_exit, + .ivsize = 8, + .maxauthsize = AES_BLOCK_SIZE, + .setkey = ccm4309_aes_nx_set_key, + .setauthsize = ccm4309_aes_nx_setauthsize, + .encrypt = ccm4309_aes_nx_encrypt, + .decrypt = ccm4309_aes_nx_decrypt, }; diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c index 436971343ff7..9a5e643af5bc 100644 --- a/drivers/crypto/nx/nx.c +++ b/drivers/crypto/nx/nx.c @@ -612,11 +612,11 @@ static int nx_register_algs(void) if (rc) goto out_unreg_gcm; - rc = nx_register_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); + rc = nx_register_aead(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); if (rc) goto out_unreg_gcm4106; - rc = nx_register_alg(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); + rc = nx_register_aead(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); if (rc) goto out_unreg_ccm; @@ -644,9 +644,9 @@ out_unreg_s256: nx_unregister_shash(&nx_shash_sha256_alg, NX_FC_SHA, NX_MODE_SHA, NX_PROPS_SHA256); out_unreg_ccm4309: - nx_unregister_alg(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); + nx_unregister_aead(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); out_unreg_ccm: - nx_unregister_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); + nx_unregister_aead(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); out_unreg_gcm4106: nx_unregister_aead(&nx_gcm4106_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); out_unreg_gcm: @@ -711,11 +711,10 @@ static int nx_crypto_ctx_init(struct nx_crypto_ctx *nx_ctx, u32 fc, u32 mode) } /* entry points from the crypto tfm initializers */ -int nx_crypto_ctx_aes_ccm_init(struct crypto_tfm *tfm) +int nx_crypto_ctx_aes_ccm_init(struct crypto_aead *tfm) { - crypto_aead_set_reqsize(__crypto_aead_cast(tfm), - sizeof(struct nx_ccm_rctx)); - return nx_crypto_ctx_init(crypto_tfm_ctx(tfm), NX_FC_AES, + crypto_aead_set_reqsize(tfm, sizeof(struct nx_ccm_rctx)); + return nx_crypto_ctx_init(crypto_aead_ctx(tfm), NX_FC_AES, NX_MODE_AES_CCM); } @@ -813,9 +812,9 @@ static int nx_remove(struct vio_dev *viodev) NX_FC_SHA, NX_MODE_SHA, NX_PROPS_SHA256); nx_unregister_shash(&nx_shash_sha256_alg, NX_FC_SHA, NX_MODE_SHA, NX_PROPS_SHA512); - nx_unregister_alg(&nx_ccm4309_aes_alg, - NX_FC_AES, NX_MODE_AES_CCM); - nx_unregister_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); + nx_unregister_aead(&nx_ccm4309_aes_alg, + NX_FC_AES, NX_MODE_AES_CCM); + nx_unregister_aead(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); nx_unregister_aead(&nx_gcm4106_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); nx_unregister_aead(&nx_gcm_aes_alg, diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h index cdff03a42ae7..8a4d1fd752d6 100644 --- a/drivers/crypto/nx/nx.h +++ b/drivers/crypto/nx/nx.h @@ -150,7 +150,7 @@ struct nx_crypto_ctx { }; /* prototypes */ -int nx_crypto_ctx_aes_ccm_init(struct crypto_tfm *tfm); +int nx_crypto_ctx_aes_ccm_init(struct crypto_aead *tfm); int nx_crypto_ctx_aes_gcm_init(struct crypto_aead *tfm); int nx_crypto_ctx_aes_xcbc_init(struct crypto_tfm *tfm); int nx_crypto_ctx_aes_ctr_init(struct crypto_tfm *tfm); @@ -189,8 +189,8 @@ extern struct aead_alg nx_gcm_aes_alg; extern struct aead_alg nx_gcm4106_aes_alg; extern struct crypto_alg nx_ctr_aes_alg; extern struct crypto_alg nx_ctr3686_aes_alg; -extern struct crypto_alg nx_ccm_aes_alg; -extern struct crypto_alg nx_ccm4309_aes_alg; +extern struct aead_alg nx_ccm_aes_alg; +extern struct aead_alg nx_ccm4309_aes_alg; extern struct shash_alg nx_shash_aes_xcbc_alg; extern struct shash_alg nx_shash_sha512_alg; extern struct shash_alg nx_shash_sha256_alg; -- cgit v1.2.3 From 039af9675fd9ce2bc1d0b02b9cb10ca9fd7a5445 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:31 -0400 Subject: crypto: nx - remove __init/__exit from VIO functions Remove the __init and __exit modifiers from the VIO driver probe and remove functions. The driver functions should not be marked __init/__exit because they can/will be called during runtime, not only at module init and exit. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index d44524da6589..fc5952000357 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -977,8 +977,8 @@ static struct nx842_driver nx842_pseries_driver = { .decompress = nx842_pseries_decompress, }; -static int __init nx842_probe(struct vio_dev *viodev, - const struct vio_device_id *id) +static int nx842_probe(struct vio_dev *viodev, + const struct vio_device_id *id) { struct nx842_devdata *old_devdata, *new_devdata = NULL; unsigned long flags; @@ -1050,7 +1050,7 @@ error: return ret; } -static int __exit nx842_remove(struct vio_dev *viodev) +static int nx842_remove(struct vio_dev *viodev) { struct nx842_devdata *old_devdata; unsigned long flags; @@ -1081,7 +1081,7 @@ static struct vio_device_id nx842_vio_driver_ids[] = { static struct vio_driver nx842_vio_driver = { .name = KBUILD_MODNAME, .probe = nx842_probe, - .remove = __exit_p(nx842_remove), + .remove = nx842_remove, .get_desired_dma = nx842_get_desired_dma, .id_table = nx842_vio_driver_ids, }; -- cgit v1.2.3 From 90fd73f912f0897bc22351b55925a4962c045086 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:32 -0400 Subject: crypto: nx - remove pSeries NX 'status' field Remove the 'status' field from the pSeries NX driver data. The 'status' field isn't used by the driver at all; it simply checks the devicetree status node at initialization, and returns success if 'okay' and failure otherwise. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 39 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index fc5952000357..b3758779dc3e 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -99,11 +99,6 @@ struct nx842_workmem { #define NX842_HW_PAGE_SIZE (4096) #define NX842_HW_PAGE_MASK (~(NX842_HW_PAGE_SIZE-1)) -enum nx842_status { - UNAVAILABLE, - AVAILABLE -}; - struct ibm_nx842_counters { atomic64_t comp_complete; atomic64_t comp_failed; @@ -121,7 +116,6 @@ static struct nx842_devdata { unsigned int max_sg_len; unsigned int max_sync_size; unsigned int max_sync_sg; - enum nx842_status status; } __rcu *devdata; static DEFINE_SPINLOCK(devdata_mutex); @@ -537,48 +531,36 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata) devdata->max_sync_size = 0; devdata->max_sync_sg = 0; devdata->max_sg_len = 0; - devdata->status = UNAVAILABLE; return 0; } else return -ENOENT; } /** - * nx842_OF_upd_status -- Update the device info from OF status prop + * nx842_OF_upd_status -- Check the device info from OF status prop * * The status property indicates if the accelerator is enabled. If the * device is in the OF tree it indicates that the hardware is present. * The status field indicates if the device is enabled when the status * is 'okay'. Otherwise the device driver will be disabled. * - * @devdata - struct nx842_devdata to update * @prop - struct property point containing the maxsyncop for the update * * Returns: * 0 - Device is available * -ENODEV - Device is not available */ -static int nx842_OF_upd_status(struct nx842_devdata *devdata, - struct property *prop) { - int ret = 0; +static int nx842_OF_upd_status(struct property *prop) +{ const char *status = (const char *)prop->value; - if (!strncmp(status, "okay", (size_t)prop->length)) { - devdata->status = AVAILABLE; - } else { - /* - * Caller will log that the device is disabled, so only - * output if there is an unexpected status. - */ - if (strncmp(status, "disabled", (size_t)prop->length)) { - dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n", - __func__, status); - } - devdata->status = UNAVAILABLE; - ret = -ENODEV; - } + if (!strncmp(status, "okay", (size_t)prop->length)) + return 0; + if (!strncmp(status, "disabled", (size_t)prop->length)) + return -ENODEV; + dev_info(devdata->dev, "%s: unknown status '%s'\n", __func__, status); - return ret; + return -EINVAL; } /** @@ -784,7 +766,7 @@ static int nx842_OF_upd(struct property *new_prop) goto out; /* Perform property updates */ - ret = nx842_OF_upd_status(new_devdata, status); + ret = nx842_OF_upd_status(status); if (ret) goto error_out; @@ -1100,7 +1082,6 @@ static int __init nx842_pseries_init(void) pr_err("Could not allocate memory for device data\n"); return -ENOMEM; } - new_devdata->status = UNAVAILABLE; RCU_INIT_POINTER(devdata, new_devdata); ret = vio_register_driver(&nx842_vio_driver); -- cgit v1.2.3 From 7f6e3aad5ab31c310b36bf0edcd305305b20e2a8 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:33 -0400 Subject: crypto: nx - move kzalloc() out of spinlock Move the kzalloc() calls in nx842_probe() and nx842_OF_upd() to the top of the functions, before taking the devdata spinlock. Since kzalloc() without GFP_ATOMIC can sleep, it can't be called while holding a spinlock. Move the calls to before taking the lock. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index b3758779dc3e..74c53a119b0b 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -724,6 +724,10 @@ static int nx842_OF_upd(struct property *new_prop) int ret = 0; unsigned long flags; + new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); + if (!new_devdata) + return -ENOMEM; + spin_lock_irqsave(&devdata_mutex, flags); old_devdata = rcu_dereference_check(devdata, lockdep_is_held(&devdata_mutex)); @@ -733,16 +737,10 @@ static int nx842_OF_upd(struct property *new_prop) if (!old_devdata || !of_node) { pr_err("%s: device is not available\n", __func__); spin_unlock_irqrestore(&devdata_mutex, flags); + kfree(new_devdata); return -ENODEV; } - new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); - if (!new_devdata) { - dev_err(old_devdata->dev, "%s: Could not allocate memory for device data\n", __func__); - ret = -ENOMEM; - goto error_out; - } - memcpy(new_devdata, old_devdata, sizeof(*old_devdata)); new_devdata->counters = old_devdata->counters; @@ -966,6 +964,17 @@ static int nx842_probe(struct vio_dev *viodev, unsigned long flags; int ret = 0; + new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); + if (!new_devdata) + return -ENOMEM; + + new_devdata->counters = kzalloc(sizeof(*new_devdata->counters), + GFP_NOFS); + if (!new_devdata->counters) { + kfree(new_devdata); + return -ENOMEM; + } + spin_lock_irqsave(&devdata_mutex, flags); old_devdata = rcu_dereference_check(devdata, lockdep_is_held(&devdata_mutex)); @@ -978,21 +987,6 @@ static int nx842_probe(struct vio_dev *viodev, dev_set_drvdata(&viodev->dev, NULL); - new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); - if (!new_devdata) { - dev_err(&viodev->dev, "%s: Could not allocate memory for device data\n", __func__); - ret = -ENOMEM; - goto error_unlock; - } - - new_devdata->counters = kzalloc(sizeof(*new_devdata->counters), - GFP_NOFS); - if (!new_devdata->counters) { - dev_err(&viodev->dev, "%s: Could not allocate memory for performance counters\n", __func__); - ret = -ENOMEM; - goto error_unlock; - } - new_devdata->vdev = viodev; new_devdata->dev = &viodev->dev; nx842_OF_set_defaults(new_devdata); -- cgit v1.2.3 From ee781b7ff3d8ab93bf99b1c3e1f0a29dda2a63e5 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:34 -0400 Subject: crypto: nx - don't register pSeries driver if ENODEV Don't register the pSeries driver when parsing the device tree returns ENODEV. The nx842_probe() function in the pSeries driver returns error instead of registering as a crypto compression driver, when it receives an error return value from the nx842_OF_upd() function that probes the device tree nodes, except when ENODEV is returned. However ENODEV should not be a special case and the driver should not register when there is no hw device, or the hw device is disabled. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-pseries.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index 74c53a119b0b..4b7bd8fb6a6b 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -999,11 +999,8 @@ static int nx842_probe(struct vio_dev *viodev, of_reconfig_notifier_register(&nx842_of_nb); ret = nx842_OF_upd(NULL); - if (ret && ret != -ENODEV) { - dev_err(&viodev->dev, "could not parse device tree. %d\n", ret); - ret = -1; + if (ret) goto error; - } rcu_read_lock(); dev_set_drvdata(&viodev->dev, rcu_dereference(devdata)); -- cgit v1.2.3 From 20fc311fc0e14d9f5ef72cfe785fd2b3f6339ab8 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:35 -0400 Subject: crypto: nx - use common code for both NX decompress success cases Replace the duplicated finishing code (set destination buffer length and set return code to 0) in the case of decompressing a buffer with no header with a goto to the success case of decompressing a buffer with a header. This is a trivial change that allows both success cases to use common code, and includes the pr_debug() msg in both cases as well. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/nx-842-crypto.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/nx-842-crypto.c b/drivers/crypto/nx/nx-842-crypto.c index 3288a701c91b..51ca168a82e9 100644 --- a/drivers/crypto/nx/nx-842-crypto.c +++ b/drivers/crypto/nx/nx-842-crypto.c @@ -520,10 +520,7 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, if (ret) goto unlock; - *dlen = p.ototal; - - ret = 0; - goto unlock; + goto success; } if (!hdr->groups) { @@ -557,6 +554,7 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, goto unlock; } +success: *dlen = p.ototal; pr_debug("decompress total slen %x dlen %x\n", slen, *dlen); -- cgit v1.2.3 From d31581a6e31f1c954704f081376e19c2014c45d3 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:36 -0400 Subject: crypto: nx - merge nx-compress and nx-compress-crypto Merge the nx-842.c code into nx-842-crypto.c. This allows later patches to remove the 'platform' driver, and instead allow each platform driver to directly register with the crypto compression api. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/Kconfig | 17 ++----- drivers/crypto/nx/Makefile | 4 +- drivers/crypto/nx/nx-842-crypto.c | 70 +++++++++++++------------- drivers/crypto/nx/nx-842.c | 103 -------------------------------------- drivers/crypto/nx/nx-842.h | 28 +++++++---- 5 files changed, 60 insertions(+), 162 deletions(-) delete mode 100644 drivers/crypto/nx/nx-842.c (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig index e421c96c763a..ad7552a6998c 100644 --- a/drivers/crypto/nx/Kconfig +++ b/drivers/crypto/nx/Kconfig @@ -14,11 +14,14 @@ config CRYPTO_DEV_NX_ENCRYPT config CRYPTO_DEV_NX_COMPRESS tristate "Compression acceleration support" default y + select CRYPTO_ALGAPI + select 842_DECOMPRESS help Support for PowerPC Nest (NX) compression acceleration. This module supports acceleration for compressing memory with the 842 - algorithm. One of the platform drivers must be selected also. - If you choose 'M' here, this module will be called nx_compress. + algorithm using the cryptographic API. One of the platform + drivers must be selected also. If you choose 'M' here, this + module will be called nx_compress. if CRYPTO_DEV_NX_COMPRESS @@ -42,14 +45,4 @@ config CRYPTO_DEV_NX_COMPRESS_POWERNV algorithm. This supports NX hardware on the PowerNV platform. If you choose 'M' here, this module will be called nx_compress_powernv. -config CRYPTO_DEV_NX_COMPRESS_CRYPTO - tristate "Compression acceleration cryptographic interface" - select CRYPTO_ALGAPI - select 842_DECOMPRESS - default y - help - Support for PowerPC Nest (NX) accelerators using the cryptographic - API. If you choose 'M' here, this module will be called - nx_compress_crypto. - endif diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile index e1684f5adb11..e29ee85b2431 100644 --- a/drivers/crypto/nx/Makefile +++ b/drivers/crypto/nx/Makefile @@ -13,9 +13,7 @@ nx-crypto-objs := nx.o \ obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o nx-compress-platform.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o -obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_CRYPTO) += nx-compress-crypto.o -nx-compress-objs := nx-842.o +nx-compress-objs := nx-842-crypto.o nx-compress-platform-objs := nx-842-platform.o nx-compress-pseries-objs := nx-842-pseries.o nx-compress-powernv-objs := nx-842-powernv.o -nx-compress-crypto-objs := nx-842-crypto.o diff --git a/drivers/crypto/nx/nx-842-crypto.c b/drivers/crypto/nx/nx-842-crypto.c index 51ca168a82e9..4472e2001e79 100644 --- a/drivers/crypto/nx/nx-842-crypto.c +++ b/drivers/crypto/nx/nx-842-crypto.c @@ -13,6 +13,9 @@ * * Copyright (C) IBM Corporation, 2011-2015 * + * Designer of the Power data compression engine: + * Bulent Abali + * * Original Authors: Robert Jennings * Seth Jennings * @@ -162,24 +165,11 @@ static void nx842_crypto_exit(struct crypto_tfm *tfm) free_page((unsigned long)ctx->dbounce); } -static int read_constraints(struct nx842_constraints *c) +static void check_constraints(struct nx842_constraints *c) { - int ret; - - ret = nx842_constraints(c); - if (ret) { - pr_err_ratelimited("could not get nx842 constraints : %d\n", - ret); - return ret; - } - /* limit maximum, to always have enough bounce buffer to decompress */ - if (c->maximum > BOUNCE_BUFFER_SIZE) { + if (c->maximum > BOUNCE_BUFFER_SIZE) c->maximum = BOUNCE_BUFFER_SIZE; - pr_info_once("limiting nx842 maximum to %x\n", c->maximum); - } - - return 0; } static int nx842_crypto_add_header(struct nx842_crypto_header *hdr, u8 *buf) @@ -260,7 +250,9 @@ nospc: timeout = ktime_add_ms(ktime_get(), COMP_BUSY_TIMEOUT); do { dlen = tmplen; /* reset dlen, if we're retrying */ - ret = nx842_compress(src, slen, dst, &dlen, ctx->wmem); + ret = nx842_platform_driver()->compress(src, slen, + dst, &dlen, + ctx->wmem); /* possibly we should reduce the slen here, instead of * retrying with the dbounce buffer? */ @@ -297,12 +289,14 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm); struct nx842_crypto_header *hdr = &ctx->header; struct nx842_crypto_param p; - struct nx842_constraints c; + struct nx842_constraints c = *nx842_platform_driver()->constraints; unsigned int groups, hdrsize, h; int ret, n; bool add_header; u16 ignore = 0; + check_constraints(&c); + p.in = (u8 *)src; p.iremain = slen; p.out = dst; @@ -311,10 +305,6 @@ static int nx842_crypto_compress(struct crypto_tfm *tfm, *dlen = 0; - ret = read_constraints(&c); - if (ret) - return ret; - groups = min_t(unsigned int, NX842_CRYPTO_GROUP_MAX, DIV_ROUND_UP(p.iremain, c.maximum)); hdrsize = NX842_CRYPTO_HEADER_SIZE(groups); @@ -381,8 +371,7 @@ static int decompress(struct nx842_crypto_ctx *ctx, struct nx842_crypto_param *p, struct nx842_crypto_header_group *g, struct nx842_constraints *c, - u16 ignore, - bool usehw) + u16 ignore) { unsigned int slen = be32_to_cpu(g->compressed_length); unsigned int required_len = be32_to_cpu(g->uncompressed_length); @@ -404,9 +393,6 @@ static int decompress(struct nx842_crypto_ctx *ctx, src += padding; - if (!usehw) - goto usesw; - if (slen % c->multiple) adj_slen = round_up(slen, c->multiple); if (slen < c->minimum) @@ -443,7 +429,9 @@ static int decompress(struct nx842_crypto_ctx *ctx, timeout = ktime_add_ms(ktime_get(), DECOMP_BUSY_TIMEOUT); do { dlen = tmplen; /* reset dlen, if we're retrying */ - ret = nx842_decompress(src, slen, dst, &dlen, ctx->wmem); + ret = nx842_platform_driver()->decompress(src, slen, + dst, &dlen, + ctx->wmem); } while (ret == -EBUSY && ktime_before(ktime_get(), timeout)); if (ret) { usesw: @@ -486,10 +474,11 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm); struct nx842_crypto_header *hdr; struct nx842_crypto_param p; - struct nx842_constraints c; + struct nx842_constraints c = *nx842_platform_driver()->constraints; int n, ret, hdr_len; u16 ignore = 0; - bool usehw = true; + + check_constraints(&c); p.in = (u8 *)src; p.iremain = slen; @@ -499,9 +488,6 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, *dlen = 0; - if (read_constraints(&c)) - usehw = false; - hdr = (struct nx842_crypto_header *)src; spin_lock_bh(&ctx->lock); @@ -516,7 +502,7 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, .uncompressed_length = cpu_to_be32(p.oremain), }; - ret = decompress(ctx, &p, &g, &c, 0, usehw); + ret = decompress(ctx, &p, &g, &c, 0); if (ret) goto unlock; @@ -549,7 +535,7 @@ static int nx842_crypto_decompress(struct crypto_tfm *tfm, if (n + 1 == hdr->groups) ignore = be16_to_cpu(hdr->ignore); - ret = decompress(ctx, &p, &hdr->group[n], &c, ignore, usehw); + ret = decompress(ctx, &p, &hdr->group[n], &c, ignore); if (ret) goto unlock; } @@ -583,6 +569,18 @@ static struct crypto_alg alg = { static int __init nx842_crypto_mod_init(void) { + request_module("nx-compress-powernv"); + request_module("nx-compress-pseries"); + + /* we prevent loading/registering if there's no platform driver, + * and we get the platform module that set it so it won't unload, + * so we don't need to check if it's set in any of our functions + */ + if (!nx842_platform_driver_get()) { + pr_err("no nx842 platform driver found.\n"); + return -ENODEV; + } + return crypto_register_alg(&alg); } module_init(nx842_crypto_mod_init); @@ -590,11 +588,13 @@ module_init(nx842_crypto_mod_init); static void __exit nx842_crypto_mod_exit(void) { crypto_unregister_alg(&alg); + + nx842_platform_driver_put(); } module_exit(nx842_crypto_mod_exit); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("IBM PowerPC Nest (NX) 842 Hardware Compression Interface"); +MODULE_DESCRIPTION("IBM PowerPC Nest (NX) 842 Hardware Compression Driver"); MODULE_ALIAS_CRYPTO("842"); MODULE_ALIAS_CRYPTO("842-nx"); MODULE_AUTHOR("Dan Streetman "); diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c deleted file mode 100644 index 6e5e0d60d0c8..000000000000 --- a/drivers/crypto/nx/nx-842.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Driver frontend for IBM Power 842 compression accelerator - * - * Copyright (C) 2015 Dan Streetman, IBM Corp - * - * Designer of the Power data compression engine: - * Bulent Abali - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "nx-842.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Dan Streetman "); -MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors"); - -/** - * nx842_constraints - * - * This provides the driver's constraints. Different nx842 implementations - * may have varying requirements. The constraints are: - * @alignment: All buffers should be aligned to this - * @multiple: All buffer lengths should be a multiple of this - * @minimum: Buffer lengths must not be less than this amount - * @maximum: Buffer lengths must not be more than this amount - * - * The constraints apply to all buffers and lengths, both input and output, - * for both compression and decompression, except for the minimum which - * only applies to compression input and decompression output; the - * compressed data can be less than the minimum constraint. It can be - * assumed that compressed data will always adhere to the multiple - * constraint. - * - * The driver may succeed even if these constraints are violated; - * however the driver can return failure or suffer reduced performance - * if any constraint is not met. - */ -int nx842_constraints(struct nx842_constraints *c) -{ - memcpy(c, nx842_platform_driver()->constraints, sizeof(*c)); - return 0; -} -EXPORT_SYMBOL_GPL(nx842_constraints); - -/** - * nx842_workmem_size - * - * Get the amount of working memory the driver requires. - */ -size_t nx842_workmem_size(void) -{ - return nx842_platform_driver()->workmem_size; -} -EXPORT_SYMBOL_GPL(nx842_workmem_size); - -int nx842_compress(const unsigned char *in, unsigned int ilen, - unsigned char *out, unsigned int *olen, void *wmem) -{ - return nx842_platform_driver()->compress(in, ilen, out, olen, wmem); -} -EXPORT_SYMBOL_GPL(nx842_compress); - -int nx842_decompress(const unsigned char *in, unsigned int ilen, - unsigned char *out, unsigned int *olen, void *wmem) -{ - return nx842_platform_driver()->decompress(in, ilen, out, olen, wmem); -} -EXPORT_SYMBOL_GPL(nx842_decompress); - -static __init int nx842_init(void) -{ - request_module("nx-compress-powernv"); - request_module("nx-compress-pseries"); - - /* we prevent loading if there's no platform driver, and we get the - * module that set it so it won't unload, so we don't need to check - * if it's set in any of the above functions - */ - if (!nx842_platform_driver_get()) { - pr_err("no nx842 driver found.\n"); - return -ENODEV; - } - - return 0; -} -module_init(nx842_init); - -static void __exit nx842_exit(void) -{ - nx842_platform_driver_put(); -} -module_exit(nx842_exit); diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h index ac0ea79d0f8b..c7dd0a4391e0 100644 --- a/drivers/crypto/nx/nx-842.h +++ b/drivers/crypto/nx/nx-842.h @@ -104,6 +104,25 @@ static inline unsigned long nx842_get_pa(void *addr) #define GET_FIELD(v, m) (((v) & (m)) >> MASK_LSH(m)) #define SET_FIELD(v, m, val) (((v) & ~(m)) | (((val) << MASK_LSH(m)) & (m))) +/** + * This provides the driver's constraints. Different nx842 implementations + * may have varying requirements. The constraints are: + * @alignment: All buffers should be aligned to this + * @multiple: All buffer lengths should be a multiple of this + * @minimum: Buffer lengths must not be less than this amount + * @maximum: Buffer lengths must not be more than this amount + * + * The constraints apply to all buffers and lengths, both input and output, + * for both compression and decompression, except for the minimum which + * only applies to compression input and decompression output; the + * compressed data can be less than the minimum constraint. It can be + * assumed that compressed data will always adhere to the multiple + * constraint. + * + * The driver may succeed even if these constraints are violated; + * however the driver can return failure or suffer reduced performance + * if any constraint is not met. + */ struct nx842_constraints { int alignment; int multiple; @@ -132,13 +151,4 @@ void nx842_platform_driver_unset(struct nx842_driver *driver); bool nx842_platform_driver_get(void); void nx842_platform_driver_put(void); -size_t nx842_workmem_size(void); - -int nx842_constraints(struct nx842_constraints *constraints); - -int nx842_compress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); -int nx842_decompress(const unsigned char *in, unsigned int in_len, - unsigned char *out, unsigned int *out_len, void *wrkmem); - #endif /* __NX_842_H__ */ -- cgit v1.2.3 From 174d66d4725879b80f8af0bda2b218c2892a9ddb Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 22 Jul 2015 14:26:37 -0400 Subject: crypto: nx - rename nx-842-crypto.c to nx-842.c The last commit merged nx-842.c's code into nx-842-crypto.c. It did not rename nx-842-crypto.c to nx-842.c, in order to let the patch more clearly show what was merged. This just renames nx-842-crypto.c to nx-842.c, with no changes to its code. Signed-off-by: Dan Streetman Signed-off-by: Herbert Xu --- drivers/crypto/nx/Makefile | 2 +- drivers/crypto/nx/nx-842-crypto.c | 600 -------------------------------------- drivers/crypto/nx/nx-842.c | 600 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 601 insertions(+), 601 deletions(-) delete mode 100644 drivers/crypto/nx/nx-842-crypto.c create mode 100644 drivers/crypto/nx/nx-842.c (limited to 'drivers/crypto/nx') diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile index e29ee85b2431..ffcc86c44e15 100644 --- a/drivers/crypto/nx/Makefile +++ b/drivers/crypto/nx/Makefile @@ -13,7 +13,7 @@ nx-crypto-objs := nx.o \ obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o nx-compress-platform.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o -nx-compress-objs := nx-842-crypto.o +nx-compress-objs := nx-842.o nx-compress-platform-objs := nx-842-platform.o nx-compress-pseries-objs := nx-842-pseries.o nx-compress-powernv-objs := nx-842-powernv.o diff --git a/drivers/crypto/nx/nx-842-crypto.c b/drivers/crypto/nx/nx-842-crypto.c deleted file mode 100644 index 4472e2001e79..000000000000 --- a/drivers/crypto/nx/nx-842-crypto.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Cryptographic API for the NX-842 hardware compression. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) IBM Corporation, 2011-2015 - * - * Designer of the Power data compression engine: - * Bulent Abali - * - * Original Authors: Robert Jennings - * Seth Jennings - * - * Rewrite: Dan Streetman - * - * This is an interface to the NX-842 compression hardware in PowerPC - * processors. Most of the complexity of this drvier is due to the fact that - * the NX-842 compression hardware requires the input and output data buffers - * to be specifically aligned, to be a specific multiple in length, and within - * specific minimum and maximum lengths. Those restrictions, provided by the - * nx-842 driver via nx842_constraints, mean this driver must use bounce - * buffers and headers to correct misaligned in or out buffers, and to split - * input buffers that are too large. - * - * This driver will fall back to software decompression if the hardware - * decompression fails, so this driver's decompression should never fail as - * long as the provided compressed buffer is valid. Any compressed buffer - * created by this driver will have a header (except ones where the input - * perfectly matches the constraints); so users of this driver can