lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 159/757] crypto: stm32/crc32 - Avoid lock if hardware is already used
    Date
    From: Nicolas Toromanoff <nicolas.toromanoff@st.com>

    [ Upstream commit bbf2cb1ea1e1428589d7f4d652bed15b265ce92d ]

    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: 7795c0baf5ac ("crypto: stm32/crc32 - protect from concurrent accesses")

    Signed-off-by: Nicolas Toromanoff <nicolas.toromanoff@st.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/crypto/stm32/Kconfig | 1 +
    drivers/crypto/stm32/stm32-crc32.c | 15 ++++++++++++---
    2 files changed, 13 insertions(+), 3 deletions(-)

    diff --git a/drivers/crypto/stm32/Kconfig b/drivers/crypto/stm32/Kconfig
    index 4ef3eb11361c2..4a4c3284ae1f3 100644
    --- a/drivers/crypto/stm32/Kconfig
    +++ b/drivers/crypto/stm32/Kconfig
    @@ -3,6 +3,7 @@ config CRYPTO_DEV_STM32_CRC
    tristate "Support for STM32 crc accelerators"
    depends on ARCH_STM32
    select CRYPTO_HASH
    + select CRC32
    help
    This enables support for the CRC32 hw accelerator which can be found
    on STMicroelectronics STM32 SOC.
    diff --git a/drivers/crypto/stm32/stm32-crc32.c b/drivers/crypto/stm32/stm32-crc32.c
    index 3ba41148c2a46..2c13f5214d2cf 100644
    --- a/drivers/crypto/stm32/stm32-crc32.c
    +++ b/drivers/crypto/stm32/stm32-crc32.c
    @@ -6,6 +6,7 @@

    #include <linux/bitrev.h>
    #include <linux/clk.h>
    +#include <linux/crc32.h>
    #include <linux/crc32poly.h>
    #include <linux/module.h>
    #include <linux/mod_devicetable.h>
    @@ -147,7 +148,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_ctx *mctx = crypto_shash_ctx(desc->tfm);
    struct stm32_crc *crc;
    - unsigned long flags;

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

    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
    @@ -195,8 +203,9 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
    /* Store partial result */
    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_put_autosuspend(crc->dev);

    --
    2.25.1


    \
     
     \ /
      Last update: 2020-10-27 17:11    [W:4.037 / U:0.260 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site