Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp992792ybt; Fri, 19 Jun 2020 20:53:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwM+m4F+BXZS5kgXE6XnPjgkRXzA5ZCoKf/DfhkkWqLFstj009myDyDyyGJrjhbphYFMLtl X-Received: by 2002:a50:f094:: with SMTP id v20mr6377237edl.77.1592625190574; Fri, 19 Jun 2020 20:53:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592625190; cv=none; d=google.com; s=arc-20160816; b=CKouPsm7kMjjaolmhDffOdHxADT3ttyuWhyNBIllb9+mwp9J4ByZblncgjlpluATxg KXMp2flQQihclUZiE8fB/Or/Q1xeynVrxb8pYGiSZyhobqSuyN10gun5yIz93ZB0cp0I ReeppKMKpjoHTrKhvP0Q+EW35Z4jNy02/ZTrKZIvW2NSir2Q3qhs/WVCkKE4PwtWLrCn IdR/7F9TEwbZlBr9gFW28cZcRYl4jFmabqYAy7uv8NJGySDlcLX0LT2rj3SEUnkEhmRU vEBYq4KwSl1hl98pZkF1l1WBTaKzBr6AmPi2tmaOAjTNQrsjQq83OnS24QWIYpc+ojD/ DMow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=SQp+LbZspVG/7URKj8D21Xz4yQ1zKjjGDERA9G9wlIg=; b=0eQ7NIUVFJcsfT0SEEVB+6Vt7BjCGw+86d3REj8Uc/qkSx1Px8tdmUWjM6JnD23/bc b1oauZAWWUdE0rjNJ613uRJ97tCXOwO6bn45jVzAwtpCZwjY29x1XGnmBBnLx0b8V0TU RRS2f7zLTf+IYGy7gmvj691OtzU5qtZ5BNvZHgSWL+PEPa6eUsg7YM4nUdipilv/uyMM H0rIumcCW31uDw41PkB8U+VyrvZPpwQt2fD7pdldh7yco28pyZm0fqdjvnIrnn27N+P0 ebNMTQ8D2mBKmK4GTqLIltjeS/eYy3eGRw2NMVwll+sCKqxC5G3Il9xbT3u4Mdf03O/g M6nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=1yRj0aoi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b5si6970983edz.386.2020.06.19.20.52.49; Fri, 19 Jun 2020 20:53:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=1yRj0aoi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405665AbgFSQW3 (ORCPT + 99 others); Fri, 19 Jun 2020 12:22:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:56532 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390623AbgFSPAM (ORCPT ); Fri, 19 Jun 2020 11:00:12 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8768521941; Fri, 19 Jun 2020 15:00:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592578811; bh=ZTU3zThxyPlECEFoIX7cZNwQcTmXBmQX+MGobFN3YjM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1yRj0aoiQI4i3wPXJSLvHLntykIK19/3KFlmZHj7GpaaPaKdC9LQNugrDd1D2L/8c DOTCzC+9g8eOyTXlF5/aMTl3m9YtwfB3BDOylK1zUIBVIhNFYWMZlZUrs83Yx6Uu0C iEesJqYd5G3kGpFBnvzCxPqE2SUhKw6jcArHY2rI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nicolas Toromanoff , Herbert Xu , Sasha Levin Subject: [PATCH 4.19 166/267] crypto: stm32/crc32 - fix ext4 chksum BUG_ON() Date: Fri, 19 Jun 2020 16:32:31 +0200 Message-Id: <20200619141656.772457231@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200619141648.840376470@linuxfoundation.org> References: <20200619141648.840376470@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Nicolas Toromanoff [ Upstream commit 49c2c082e00e0bc4f5cbb7c21c7f0f873b35ab09 ] Allow use of crc_update without prior call to crc_init. And change (and fix) driver to use CRC device even on unaligned buffers. Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module") Signed-off-by: Nicolas Toromanoff Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/stm32/stm32_crc32.c | 98 +++++++++++++++--------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/drivers/crypto/stm32/stm32_crc32.c b/drivers/crypto/stm32/stm32_crc32.c index 29d2095d9dfd..749b51762b18 100644 --- a/drivers/crypto/stm32/stm32_crc32.c +++ b/drivers/crypto/stm32/stm32_crc32.c @@ -28,8 +28,10 @@ /* Registers values */ #define CRC_CR_RESET BIT(0) -#define CRC_CR_REVERSE (BIT(7) | BIT(6) | BIT(5)) #define CRC_INIT_DEFAULT 0xFFFFFFFF +#define CRC_CR_REV_IN_WORD (BIT(6) | BIT(5)) +#define CRC_CR_REV_IN_BYTE BIT(5) +#define CRC_CR_REV_OUT BIT(7) #define CRC_AUTOSUSPEND_DELAY 50 @@ -38,8 +40,6 @@ struct stm32_crc { struct device *dev; void __iomem *regs; struct clk *clk; - u8 pending_data[sizeof(u32)]; - size_t nb_pending_bytes; }; struct stm32_crc_list { @@ -59,7 +59,6 @@ struct stm32_crc_ctx { struct stm32_crc_desc_ctx { u32 partial; /* crc32c: partial in first 4 bytes of that struct */ - struct stm32_crc *crc; }; static int stm32_crc32_cra_init(struct crypto_tfm *tfm) @@ -101,25 +100,22 @@ static int stm32_crc_init(struct shash_desc *desc) struct stm32_crc *crc; spin_lock_bh(&crc_list.lock); - list_for_each_entry(crc, &crc_list.dev_list, list) { - ctx->crc = crc; - break; - } + crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list); spin_unlock_bh(&crc_list.lock); - pm_runtime_get_sync(ctx->crc->dev); + pm_runtime_get_sync(crc->dev); /* Reset, set key, poly and configure in bit reverse mode */ - writel_relaxed(bitrev32(mctx->key), ctx->crc->regs + CRC_INIT); - writel_relaxed(bitrev32(mctx->poly), ctx->crc->regs + CRC_POL); - writel_relaxed(CRC_CR_RESET | CRC_CR_REVERSE, ctx->crc->regs + CRC_CR); + writel_relaxed(bitrev32(mctx->key), crc->regs + CRC_INIT); + writel_relaxed(bitrev32(mctx->poly), crc->regs + CRC_POL); + writel_relaxed(CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); /* Store partial result */ - ctx->partial = readl_relaxed(ctx->crc->regs + CRC_DR); - ctx->crc->nb_pending_bytes = 0; + ctx->partial = readl_relaxed(crc->regs + CRC_DR); - pm_runtime_mark_last_busy(ctx->crc->dev); - pm_runtime_put_autosuspend(ctx->crc->dev); + pm_runtime_mark_last_busy(crc->dev); + pm_runtime_put_autosuspend(crc->dev); return 0; } @@ -128,31 +124,49 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8, unsigned int length) { struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc); - struct stm32_crc *crc = ctx->crc; - u32 *d32; - unsigned int i; + struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm); + struct stm32_crc *crc; + + spin_lock_bh(&crc_list.lock); + crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list); + spin_unlock_bh(&crc_list.lock); pm_runtime_get_sync(crc->dev); - if (unlikely(crc->nb_pending_bytes)) { - while (crc->nb_pending_bytes != sizeof(u32) && length) { - /* Fill in pending data */ - crc->pending_data[crc->nb_pending_bytes++] = *(d8++); + /* + * Restore previously calculated CRC for this context as init value + * Restore polynomial configuration + * Configure in register for word input data, + * Configure out register in reversed bit mode data. + */ + writel_relaxed(bitrev32(ctx->partial), crc->regs + CRC_INIT); + writel_relaxed(bitrev32(mctx->poly), crc->regs + CRC_POL); + writel_relaxed(CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + + if (d8 != PTR_ALIGN(d8, sizeof(u32))) { + /* Configure for byte data */ + writel_relaxed(CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + while (d8 != PTR_ALIGN(d8, sizeof(u32)) && length) { + writeb_relaxed(*d8++, crc->regs + CRC_DR); length--; } - - if (crc->nb_pending_bytes == sizeof(u32)) { - /* Process completed pending data */ - writel_relaxed(*(u32 *)crc->pending_data, - crc->regs + CRC_DR); - crc->nb_pending_bytes = 0; - } + /* Configure for word data */ + writel_relaxed(CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); } - d32 = (u32 *)d8; - for (i = 0; i < length >> 2; i++) - /* Process 32 bits data */ - writel_relaxed(*(d32++), crc->regs + CRC_DR); + for (; length >= sizeof(u32); d8 += sizeof(u32), length -= sizeof(u32)) + writel_relaxed(*((u32 *)d8), crc->regs + CRC_DR); + + if (length) { + /* Configure for byte data */ + writel_relaxed(CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + while (length--) + writeb_relaxed(*d8++, crc->regs + CRC_DR); + } /* Store partial result */ ctx->partial = readl_relaxed(crc->regs + CRC_DR); @@ -160,22 +174,6 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8, pm_runtime_mark_last_busy(crc->dev); pm_runtime_put_autosuspend(crc->dev); - /* Check for pending data (non 32 bits) */ - length &= 3; - if (likely(!length)) - return 0; - - if ((crc->nb_pending_bytes + length) >= sizeof(u32)) { - /* Shall not happen */ - dev_err(crc->dev, "Pending data overflow\n"); - return -EINVAL; - } - - d8 = (const u8 *)d32; - for (i = 0; i < length; i++) - /* Store pending data */ - crc->pending_data[crc->nb_pending_bytes++] = *(d8++); - return 0; } -- 2.25.1