diff options
author | Trusted Logic <smc_support@trusted-logic.com> | 2012-02-01 13:36:59 -0600 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:56:20 +0200 |
commit | a9dbbe316b6ea7e18d84ac55f2f11cdde2ca501b (patch) | |
tree | 3a9ebc030d101d45b4c0be1ca6f1d96a01c0fa15 /security/smc/tf_crypto_digest.c | |
parent | 118b19090e2a94c8c9e7ca2b747b1fcfa123d250 (diff) | |
download | kernel_samsung_tuna-a9dbbe316b6ea7e18d84ac55f2f11cdde2ca501b.zip kernel_samsung_tuna-a9dbbe316b6ea7e18d84ac55f2f11cdde2ca501b.tar.gz kernel_samsung_tuna-a9dbbe316b6ea7e18d84ac55f2f11cdde2ca501b.tar.bz2 |
SMC: Fix PA load error 0xffff3020
Fix "Error while loading the PA [0xffff3020]"
Improve synchronous public crypto.
WARNING: using this patch with an older PA binary (before MSHIELD
v1.7.5) will result in a PA load error. This patch is coupled with
changes in the secure PA (cache flush/invalidiation)
Change-Id: I3c3b7c41917b1146d6cb6f29ee33848eb9c3c0dc
Signed-off-by: Trusted Logic <smc_support@trusted-logic.com>
Signed-off-by: Bryan Buckley <bryan.buckley@ti.com>
Diffstat (limited to 'security/smc/tf_crypto_digest.c')
-rw-r--r-- | security/smc/tf_crypto_digest.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/security/smc/tf_crypto_digest.c b/security/smc/tf_crypto_digest.c index 8023839..590b6c1 100644 --- a/security/smc/tf_crypto_digest.c +++ b/security/smc/tf_crypto_digest.c @@ -465,17 +465,33 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength, struct omap_dma_channel_params ch0_parameters; u32 length_loop = 0; u32 algo_constant; + u8 *local_buf = NULL; + dma_addr_t local_buf_phys; struct tf_device *dev = tf_get_device(); + bool ret = true; dpr_info( "%s: Buffer=0x%08x/%u\n", __func__, (u32)data, (u32)nDataLength); /*lock the DMA */ - mutex_lock(&dev->sm.dma_mutex); + if (!mutex_trylock(&dev->sm.dma_mutex)) { + local_buf = dma_alloc_coherent(NULL, dev->dma_buffer_length, + &local_buf_phys, GFP_KERNEL); + if (local_buf == NULL) { + printk(KERN_ERR "SMC: DMA buffer is already taken " + "and %s could not allocate a temporary one\n", + __func__); + return false; + } + } else { + local_buf = dev->dma_buffer; + local_buf_phys = dev->dma_buffer_phys; + } + if (tf_dma_request(&dma_ch0) != PUBLIC_CRYPTO_OPERATION_SUCCESS) { - mutex_unlock(&dev->sm.dma_mutex); - return false; + ret = false; + goto exit; } while (nDataLength > 0) { @@ -498,11 +514,10 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength, * buffer which has correct properties from efficient DMA * transfers. */ - if (tf_cpy_from( - dev->dma_buffer, data, length_loop, buffer_origin)) { + if (tf_cpy_from(local_buf, data, length_loop, buffer_origin)) { omap_free_dma(dma_ch0); - mutex_unlock(&dev->sm.dma_mutex); - return false; + ret = false; + goto exit; } /*DMA1: Mem -> HASH */ @@ -510,7 +525,7 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength, length_loop / HASH_BLOCK_BYTES_LENGTH, DMA_CEN_Elts_per_Frame_SHA, DIGEST1_REGS_HW_ADDR + 0x80, - dev->dma_buffer_phys, + local_buf_phys, OMAP44XX_DMA_SHA2_DIN_P); /*specific for Mem -> HWA */ @@ -553,13 +568,11 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength, } /*For safety reasons, let's clean the working buffer */ - memset(dev->dma_buffer, 0, length_loop); + memset(local_buf, 0, length_loop); /*release the DMA */ omap_free_dma(dma_ch0); - mutex_unlock(&dev->sm.dma_mutex); - /* * The dma transfert is finished, now wait until the hash * operation is finished. @@ -568,7 +581,14 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength, (u32 *)&sha1_md5_reg->IRQSTATUS, DIGEST_IRQSTATUS_CONTEXT_READY_BIT); - return true; +exit: + if (dev->dma_buffer == local_buf) + mutex_unlock(&dev->sm.dma_mutex); + else + dma_free_coherent(NULL, dev->dma_buffer_length, + local_buf, local_buf_phys); + + return ret; } /*------------------------------------------------------------------------- */ |