aboutsummaryrefslogtreecommitdiffstats
path: root/security/smc/tf_crypto_digest.c
diff options
context:
space:
mode:
authorTrusted Logic <smc_support@trusted-logic.com>2012-02-01 13:36:59 -0600
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:56:20 +0200
commita9dbbe316b6ea7e18d84ac55f2f11cdde2ca501b (patch)
tree3a9ebc030d101d45b4c0be1ca6f1d96a01c0fa15 /security/smc/tf_crypto_digest.c
parent118b19090e2a94c8c9e7ca2b747b1fcfa123d250 (diff)
downloadkernel_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.c44
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;
}
/*------------------------------------------------------------------------- */