Commit bbf2cb1e authored by Nicolas Toromanoff's avatar Nicolas Toromanoff Committed by Herbert Xu
Browse files

crypto: stm32/crc32 - Avoid lock if hardware is already used



If STM32 CRC device is already in use, calculate CRC by software.

This will release CPU constraint for a concurrent access to the
hardware, and avoid masking irqs during the whole block processing.

Fixes: 7795c0ba ("crypto: stm32/crc32 - protect from concurrent accesses")

Signed-off-by: default avatarNicolas Toromanoff <nicolas.toromanoff@st.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c4c75fcb
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -3,6 +3,7 @@ config CRYPTO_DEV_STM32_CRC
	tristate "Support for STM32 crc accelerators"
	tristate "Support for STM32 crc accelerators"
	depends on ARCH_STM32
	depends on ARCH_STM32
	select CRYPTO_HASH
	select CRYPTO_HASH
	select CRC32
	help
	help
	  This enables support for the CRC32 hw accelerator which can be found
	  This enables support for the CRC32 hw accelerator which can be found
	  on STMicroelectronics STM32 SOC.
	  on STMicroelectronics STM32 SOC.
+12 −3
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@


#include <linux/bitrev.h>
#include <linux/bitrev.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/crc32poly.h>
#include <linux/crc32poly.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
@@ -149,7 +150,6 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
	struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
	struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
	struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
	struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
	struct stm32_crc *crc;
	struct stm32_crc *crc;
	unsigned long flags;


	crc = stm32_crc_get_next_crc();
	crc = stm32_crc_get_next_crc();
	if (!crc)
	if (!crc)
@@ -157,7 +157,15 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,


	pm_runtime_get_sync(crc->dev);
	pm_runtime_get_sync(crc->dev);


	spin_lock_irqsave(&crc->lock, flags);
	if (!spin_trylock(&crc->lock)) {
		/* Hardware is busy, calculate crc32 by software */
		if (mctx->poly == CRC32_POLY_LE)
			ctx->partial = crc32_le(ctx->partial, d8, length);
		else
			ctx->partial = __crc32c_le(ctx->partial, d8, length);

		goto pm_out;
	}


	/*
	/*
	 * Restore previously calculated CRC for this context as init value
	 * Restore previously calculated CRC for this context as init value
@@ -197,8 +205,9 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
	/* Store partial result */
	/* Store partial result */
	ctx->partial = readl_relaxed(crc->regs + CRC_DR);
	ctx->partial = readl_relaxed(crc->regs + CRC_DR);


	spin_unlock_irqrestore(&crc->lock, flags);
	spin_unlock(&crc->lock);


pm_out:
	pm_runtime_mark_last_busy(crc->dev);
	pm_runtime_mark_last_busy(crc->dev);
	pm_runtime_put_autosuspend(crc->dev);
	pm_runtime_put_autosuspend(crc->dev);