From patchwork Fri Jun 2 12:24:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gstir X-Patchwork-Id: 9762439 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CDF016038E for ; Fri, 2 Jun 2017 12:25:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C482E28506 for ; Fri, 2 Jun 2017 12:25:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B90822852A; Fri, 2 Jun 2017 12:25:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BAF628521 for ; Fri, 2 Jun 2017 12:25:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751417AbdFBMZF (ORCPT ); Fri, 2 Jun 2017 08:25:05 -0400 Received: from mail.sigma-star.at ([95.130.255.111]:45998 "EHLO mail.sigma-star.at" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751157AbdFBMZE (ORCPT ); Fri, 2 Jun 2017 08:25:04 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.sigma-star.at (Postfix) with ESMTP id 4040724E0002; Fri, 2 Jun 2017 14:24:59 +0200 (CEST) Received: from spire.fritz.box (david_mobile.vpn.sigmapriv.at [10.3.0.121]) by mail.sigma-star.at (Postfix) with ESMTPSA id 2A2BB24E0004; Fri, 2 Jun 2017 14:24:58 +0200 (CEST) From: David Gstir To: horia.geanta@nxp.com, dan.douglass@nxp.com, herbert@gondor.apana.org.au, davem@davemloft.net Cc: richard@sigma-star.at, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, David Gstir Subject: [RFC PATCH 2/2] crypto: caam - fix k*alloc if called from own cipher callback Date: Fri, 2 Jun 2017 14:24:46 +0200 Message-Id: <20170602122446.2427-3-david@sigma-star.at> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170602122446.2427-1-david@sigma-star.at> References: <20170602122446.2427-1-david@sigma-star.at> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are cases (e.g. the cts mode) where a cipher can be called again from its own callback. In our case this callback is executed from within a tasklet in the jobring, we must not sleep when allocating memory. This patch detects such cases by using in_interrupt() to properly set the k*alloc flags. In most cases we will still use GFP_KERNEL if the flags CRYPTO_TFM_REQ_MAY_SLEEP or CRYPTO_TFM_REQ_MAY_BACKLOG are set for the cipher request. Signed-off-by: David Gstir --- drivers/crypto/caam/caamalg.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index d13c1aee4427..4c4a5d1ad875 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1209,13 +1209,18 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, struct crypto_aead *aead = crypto_aead_reqtfm(req); struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; - gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC; + gfp_t flags; int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; struct aead_edesc *edesc; int sec4_sg_index, sec4_sg_len, sec4_sg_bytes; unsigned int authsize = ctx->authsize; + if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) + flags = GFP_KERNEL; + else + flags = GFP_ATOMIC; + if (unlikely(req->dst != req->src)) { src_nents = sg_nents_for_len(req->src, req->assoclen + req->cryptlen); @@ -1497,9 +1502,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); struct device *jrdev = ctx->jrdev; - gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP)) ? - GFP_KERNEL : GFP_ATOMIC; + gfp_t flags; int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; struct ablkcipher_edesc *edesc; dma_addr_t iv_dma = 0; @@ -1507,6 +1510,12 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request int ivsize = crypto_ablkcipher_ivsize(ablkcipher); int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes; + if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) + flags = GFP_KERNEL; + else + flags = GFP_ATOMIC; + src_nents = sg_nents_for_len(req->src, req->nbytes); if (unlikely(src_nents < 0)) { dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n", @@ -1703,9 +1712,7 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc( struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); struct device *jrdev = ctx->jrdev; - gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP)) ? - GFP_KERNEL : GFP_ATOMIC; + gfp_t flags; int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents; struct ablkcipher_edesc *edesc; dma_addr_t iv_dma = 0; @@ -1713,6 +1720,12 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc( int ivsize = crypto_ablkcipher_ivsize(ablkcipher); int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes; + if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) + flags = GFP_KERNEL; + else + flags = GFP_ATOMIC; + src_nents = sg_nents_for_len(req->src, req->nbytes); if (unlikely(src_nents < 0)) { dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",