aboutsummaryrefslogtreecommitdiffstats
path: root/security/smc
diff options
context:
space:
mode:
authorTrusted Logic <smc_support@trusted-logic.com>2012-02-01 13:36:59 -0600
committerDan Murphy <dmurphy@ti.com>2012-02-03 08:33:45 -0600
commit3d9717cb9a30d86875077f1b01a6078e08b9cb0c (patch)
treec64f109c2d9f92d497bb354127ef4d2c357a36ca /security/smc
parent54463ad977ee1c374722e102445251044dc36669 (diff)
downloadkernel_samsung_espresso10-3d9717cb9a30d86875077f1b01a6078e08b9cb0c.zip
kernel_samsung_espresso10-3d9717cb9a30d86875077f1b01a6078e08b9cb0c.tar.gz
kernel_samsung_espresso10-3d9717cb9a30d86875077f1b01a6078e08b9cb0c.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')
-rw-r--r--security/smc/tf_comm_mshield.c5
-rw-r--r--security/smc/tf_crypto.c2
-rw-r--r--security/smc/tf_crypto_aes.c3
-rw-r--r--security/smc/tf_crypto_digest.c44
-rw-r--r--security/smc/tf_device.c2
-rw-r--r--security/smc/tf_device_mshield.c2
-rw-r--r--security/smc/tf_self_test_post.c5
7 files changed, 39 insertions, 24 deletions
diff --git a/security/smc/tf_comm_mshield.c b/security/smc/tf_comm_mshield.c
index 4569343..b5279fe 100644
--- a/security/smc/tf_comm_mshield.c
+++ b/security/smc/tf_comm_mshield.c
@@ -459,11 +459,6 @@ static u32 tf_rpc_init(struct tf_comm *comm)
spin_lock(&(comm->lock));
- dmac_flush_range((void *)comm->l1_buffer,
- (void *)(((u32)(comm->l1_buffer)) + PAGE_SIZE));
- outer_inv_range(__pa(comm->l1_buffer),
- __pa(comm->l1_buffer) + PAGE_SIZE);
-
protocol_version = comm->l1_buffer->protocol_version;
if ((GET_PROTOCOL_MAJOR_VERSION(protocol_version))
diff --git a/security/smc/tf_crypto.c b/security/smc/tf_crypto.c
index baed463..1be70ce 100644
--- a/security/smc/tf_crypto.c
+++ b/security/smc/tf_crypto.c
@@ -233,7 +233,7 @@ u32 tf_crypto_init(void)
mutex_init(&dev->sm.dma_mutex);
/*allocate DMA buffer */
- dev->dma_buffer_length = PAGE_SIZE * 16;
+ dev->dma_buffer_length = PAGE_SIZE;
dev->dma_buffer = dma_alloc_coherent(NULL,
dev->dma_buffer_length,
&(dev->dma_buffer_phys),
diff --git a/security/smc/tf_crypto_aes.c b/security/smc/tf_crypto_aes.c
index cb340a3..24d5787 100644
--- a/security/smc/tf_crypto_aes.c
+++ b/security/smc/tf_crypto_aes.c
@@ -694,6 +694,7 @@ static int aes_dma_start(struct aes_hwa_ctx *ctx)
struct tf_crypto_aes_operation_state *state =
crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(ctx->req));
static size_t last_count;
+ unsigned long flags;
in = IS_ALIGNED((u32)ctx->in_sg->offset, sizeof(u32));
out = IS_ALIGNED((u32)ctx->out_sg->offset, sizeof(u32));
@@ -829,6 +830,7 @@ static int aes_dma_start(struct aes_hwa_ctx *ctx)
omap_start_dma(ctx->dma_lch_in);
omap_start_dma(ctx->dma_lch_out);
+ spin_lock_irqsave(&ctx->lock, flags);
if (ctx->next_req) {
struct ablkcipher_request *req =
ablkcipher_request_cast(ctx->next_req);
@@ -855,6 +857,7 @@ static int aes_dma_start(struct aes_hwa_ctx *ctx)
ctx->backlog->complete(ctx->backlog, -EINPROGRESS);
ctx->backlog = NULL;
}
+ spin_unlock_irqrestore(&ctx->lock, flags);
return 0;
}
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;
}
/*------------------------------------------------------------------------- */
diff --git a/security/smc/tf_device.c b/security/smc/tf_device.c
index df11669..fdcb5eb 100644
--- a/security/smc/tf_device.c
+++ b/security/smc/tf_device.c
@@ -388,7 +388,7 @@ static int __init tf_device_register(void)
}
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
- error = tf_self_test_post_init(&(dev_stats->kobj));
+ error = tf_self_test_post_init(&(g_tf_dev.kobj));
/* N.B. error > 0 indicates a POST failure, which will not
prevent the module from loading. */
if (error < 0) {
diff --git a/security/smc/tf_device_mshield.c b/security/smc/tf_device_mshield.c
index 0fa30a9..614c71a 100644
--- a/security/smc/tf_device_mshield.c
+++ b/security/smc/tf_device_mshield.c
@@ -364,7 +364,6 @@ void __exit tf_device_mshield_exit(void)
if (dev == NULL)
return;
- mutex_lock(&dev->dev_mutex);
if (tf_ctrl_class != NULL) {
device_destroy(tf_ctrl_class, dev->dev_number + 1);
class_destroy(tf_ctrl_class);
@@ -372,7 +371,6 @@ void __exit tf_device_mshield_exit(void)
}
cdev_del(&(dev->cdev_ctrl));
unregister_chrdev_region(dev->dev_number + 1, 1);
- mutex_unlock(&dev->dev_mutex);
dev->workspace_size = 0;
dev->workspace_addr = 0;
diff --git a/security/smc/tf_self_test_post.c b/security/smc/tf_self_test_post.c
index 650bf17..1e8259c 100644
--- a/security/smc/tf_self_test_post.c
+++ b/security/smc/tf_self_test_post.c
@@ -563,9 +563,8 @@ struct tf_post_data {
};
static const struct attribute tf_post_failures_attr = {
- "failures",
- THIS_MODULE,
- 0444
+ .name = "failures",
+ .mode = 0444,
};
static ssize_t tf_post_kobject_show(struct kobject *kobj,