aboutsummaryrefslogtreecommitdiffstats
path: root/security/smc
diff options
context:
space:
mode:
authorTrusted Logic <smc_support@trusted-logic.com>2012-05-09 13:22:41 -0500
committerDmytro Kedrovskyi <x0169235@ti.com>2012-06-12 19:39:53 +0300
commit9b0673eabf35cd5b7810276e826105178031fbf3 (patch)
treea1b9621fe301833d7f5b474c814531f56a8f074a /security/smc
parentdfb7f3443f8e8428d1ee3a26ac4bd9a905ef0967 (diff)
downloadkernel_samsung_espresso10-9b0673eabf35cd5b7810276e826105178031fbf3.zip
kernel_samsung_espresso10-9b0673eabf35cd5b7810276e826105178031fbf3.tar.gz
kernel_samsung_espresso10-9b0673eabf35cd5b7810276e826105178031fbf3.tar.bz2
SMC: Update to AG01.06p4 release
With this SMC driver version present in MSHIELD-DK 1.7.10 and using corresponding PPA/PA, the crypto driver now uses DMA beyond a certain data size threshold. It fixes some statbility issues observed since introduction of DMA in MSHIELD-DK release 1.7.2 * start using GFP_ATOMIC instead of GFP_KERNEL in aes_sync_operate() and tf_digest_hw_perform_dma() * tf_clock_timer_start() now called in tf_clock_timer_cbis() * fixed potential memory leak in aes_sync_operate Change-Id: Ifcb4653b0cad7dc2e5cf61bd58631c56d7738dd7 Signed-off-by: Trusted Logic <smc_support@trusted-logic.com> Signed-off-by: Bryan Buckley <bryan.buckley@ti.com> Signed-off-by: Srinivas Pulukuru <srinivas.pulukuru@ti.com>
Diffstat (limited to 'security/smc')
-rw-r--r--security/smc/s_version.h2
-rw-r--r--security/smc/tf_comm.c31
-rw-r--r--security/smc/tf_comm_mshield.c9
-rw-r--r--security/smc/tf_conn.c10
-rw-r--r--security/smc/tf_crypto_aes.c38
-rw-r--r--security/smc/tf_crypto_digest.c2
-rw-r--r--security/smc/tf_device.c8
-rw-r--r--security/smc/tf_zebra.h5
8 files changed, 72 insertions, 33 deletions
diff --git a/security/smc/s_version.h b/security/smc/s_version.h
index 016e5de..68453ac 100644
--- a/security/smc/s_version.h
+++ b/security/smc/s_version.h
@@ -45,7 +45,7 @@
* defines to set the version number. Else set these values to 0.
*/
#define S_VERSION_ENG 0
-#define S_VERSION_PATCH 0
+#define S_VERSION_PATCH 4
#ifdef S_VERSION_BUILD
/* TRICK: detect if S_VERSION is defined but empty */
diff --git a/security/smc/tf_comm.c b/security/smc/tf_comm.c
index 59733f8..1a01658 100644
--- a/security/smc/tf_comm.c
+++ b/security/smc/tf_comm.c
@@ -492,7 +492,6 @@ inline struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor)
return pte_page(l2_page_descriptor & L2_DESCRIPTOR_ADDR_MASK);
}
-#define TF_DEFAULT_COMMON_DESCRIPTORS 0x0000044C
/*
* Returns the L1 descriptor for the 1KB-aligned coarse page table. The address
@@ -502,19 +501,41 @@ static void tf_get_l2_page_descriptor(
u32 *l2_page_descriptor,
u32 flags, struct mm_struct *mm)
{
+ unsigned long page_vaddr;
u32 descriptor;
struct page *page;
+ bool unmap_page = false;
+#if 0
dprintk(KERN_INFO
- "%s *l2_page_descriptor=%x vm_flags=%lx\n",
- __func__, *l2_page_descriptor, vmas->vm_flags);
+ "tf_get_l2_page_descriptor():"
+ "*l2_page_descriptor=%x\n",
+ *l2_page_descriptor);
+#endif
if (*l2_page_descriptor == L2_DESCRIPTOR_FAULT)
return;
page = (struct page *) (*l2_page_descriptor);
- descriptor = TF_DEFAULT_COMMON_DESCRIPTORS;
+ page_vaddr = (unsigned long) page_address(page);
+ if (page_vaddr == 0) {
+ dprintk(KERN_INFO "page_address returned 0\n");
+ /* Should we use kmap_atomic(page, KM_USER0) instead ? */
+ page_vaddr = (unsigned long) kmap(page);
+ if (page_vaddr == 0) {
+ *l2_page_descriptor = L2_DESCRIPTOR_FAULT;
+ dprintk(KERN_ERR "kmap returned 0\n");
+ return;
+ }
+ unmap_page = true;
+ }
+
+ descriptor = tf_get_l2_descriptor_common(page_vaddr, mm);
+ if (descriptor == 0) {
+ *l2_page_descriptor = L2_DESCRIPTOR_FAULT;
+ return;
+ }
descriptor |= L2_PAGE_DESCRIPTOR_BASE;
descriptor |= (page_to_phys(page) & L2_DESCRIPTOR_ADDR_MASK);
@@ -526,6 +547,8 @@ static void tf_get_l2_page_descriptor(
/* read and write access */
descriptor |= L2_PAGE_DESCRIPTOR_AP_APX_READ_WRITE;
+ if (unmap_page)
+ kunmap(page);
*l2_page_descriptor = descriptor;
}
diff --git a/security/smc/tf_comm_mshield.c b/security/smc/tf_comm_mshield.c
index b5279fe..5d3bd26 100644
--- a/security/smc/tf_comm_mshield.c
+++ b/security/smc/tf_comm_mshield.c
@@ -190,8 +190,12 @@ static void tf_clock_timer_cb(unsigned long data)
* DES : 1 << 1
* AES1 : 1 << 2
* AES2 : 1 << 3
+ * RNG : 1 << 4
+ * PKA : 1 << 5
+ *
+ * Clock patch active: 1 << 7
*/
- if (ret & 0xf)
+ if (ret & 0x3f)
goto restart;
wake_unlock(&g_tf_wake_lock);
@@ -684,6 +688,8 @@ int tf_start(struct tf_comm *comm,
workspace_size -= 0x20000;
sdp_bkext_store_addr = workspace_addr + workspace_size;
+ tf_clock_timer_start();
+
if (test_bit(TF_COMM_FLAG_PA_AVAILABLE, &comm->flags)) {
dpr_err("%s(%p): The SMC PA is already started\n",
__func__, comm);
@@ -871,6 +877,7 @@ error1:
}
exit:
+ tf_clock_timer_stop();
#ifdef CONFIG_SMP
ret_affinity = sched_setaffinity(0, &saved_cpu_mask);
if (ret_affinity != 0)
diff --git a/security/smc/tf_conn.c b/security/smc/tf_conn.c
index 27ac1a0..ad40075 100644
--- a/security/smc/tf_conn.c
+++ b/security/smc/tf_conn.c
@@ -36,6 +36,7 @@
#include "tf_conn.h"
#ifdef CONFIG_TF_ZEBRA
+#include "tf_zebra.h"
#include "tf_crypto.h"
#endif
@@ -1123,11 +1124,6 @@ error:
}
-
-#ifdef CONFIG_TF_ION
-extern struct ion_device *omap_ion_device;
-#endif /* CONFIG_TF_ION */
-
/*
* Invokes a client command to the Secure World
*/
@@ -1187,9 +1183,9 @@ int tf_invoke_client_command(
if (connection->ion_client == NULL) {
connection->ion_client = ion_client_create(
- omap_ion_device,
+ zebra_ion_device,
(1 << ION_HEAP_TYPE_CARVEOUT),
- "smc");
+ "tf");
}
if (connection->ion_client == NULL) {
dprintk(KERN_ERR "%s(%p): "
diff --git a/security/smc/tf_crypto_aes.c b/security/smc/tf_crypto_aes.c
index 75995e8..fb744b1 100644
--- a/security/smc/tf_crypto_aes.c
+++ b/security/smc/tf_crypto_aes.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
+#include <linux/mempool.h>
#include <crypto/algapi.h>
#include <crypto/scatterwalk.h>
#include <crypto/aes.h>
@@ -1190,30 +1191,32 @@ static void aes_sync_op_complete(
struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
/* Notify crypto operation has finished */
- complete((struct completion *) req->base.data);
+ atomic_set((atomic_t *) req->base.data, 0);
}
+#define MIN_SYNC_REQ 8
+static mempool_t *req_pool;
+
static int aes_sync_operate(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes, int encrypt)
{
struct ablkcipher_request *req;
struct aes_reqctx *rctx;
- int err;
- DECLARE_COMPLETION(aes_sync_op_completion);
+ int err = 0;
+ atomic_t pending = ATOMIC_INIT(1);
if (nbytes % AES_BLOCK_SIZE)
return -EINVAL;
- req = kmalloc(sizeof(struct ablkcipher_request) +
- sizeof(struct aes_reqctx), GFP_KERNEL);
+ req = mempool_alloc(req_pool, GFP_ATOMIC);
if (req == NULL)
return -ENOMEM;
req->base.tfm = crypto_blkcipher_tfm(desc->tfm);
ablkcipher_request_set_crypt(req, src, dst, nbytes, desc->info);
ablkcipher_request_set_callback(req, desc->flags,
- aes_sync_op_complete, &aes_sync_op_completion);
+ aes_sync_op_complete, &pending);
rctx = ablkcipher_request_ctx(req);
rctx->mode = encrypt ? FLAGS_ENCRYPT : FLAGS_DECRYPT;
@@ -1225,15 +1228,17 @@ static int aes_sync_operate(struct blkcipher_desc *desc,
break;
default:
- return err;
+ goto out;
}
/* Wait for crypto operation to be actually finished */
- wait_for_completion(&aes_sync_op_completion);
+ while (atomic_read(&pending))
+ cpu_relax();
- kzfree(req);
+out:
+ mempool_free(req, req_pool);
- return 0;
+ return err;
}
static int aes_sync_encrypt(struct blkcipher_desc *desc,
@@ -1341,7 +1346,7 @@ static void aes_cra_exit(struct crypto_tfm *tfm)
static struct crypto_alg smc_aes_ecb_sync_alg = {
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_priority = 999,
- .cra_name = "ecb(aes)",
+ .cra_name = "ecb(aes-hw)",
.cra_driver_name = "aes-ecb-smc",
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
@@ -1364,7 +1369,7 @@ static struct crypto_alg smc_aes_ecb_sync_alg = {
static struct crypto_alg smc_aes_cbc_sync_alg = {
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_priority = 999,
- .cra_name = "cbc(aes)",
+ .cra_name = "cbc(aes-hw)",
.cra_driver_name = "aes-cbc-smc",
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
@@ -1388,7 +1393,7 @@ static struct crypto_alg smc_aes_cbc_sync_alg = {
static struct crypto_alg smc_aes_ctr_sync_alg = {
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_priority = 999,
- .cra_name = "ctr(aes)",
+ .cra_name = "ctr(aes-hw)",
.cra_driver_name = "aes-ctr-smc",
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
@@ -1510,6 +1515,11 @@ int register_smc_public_crypto_aes(void)
if (ret)
goto err_dma;
+ req_pool = mempool_create_kmalloc_pool(MIN_SYNC_REQ,
+ sizeof(struct ablkcipher_request) + sizeof(struct aes_reqctx));
+ if (req_pool == NULL)
+ goto err_dma;
+
ret = crypto_register_alg(&smc_aes_ecb_sync_alg);
if (ret)
goto err_ecb_sync;
@@ -1571,6 +1581,8 @@ void unregister_smc_public_crypto_aes(void)
tasklet_kill(&aes_ctx->task);
kfree(aes_ctx);
+
+ mempool_destroy(req_pool);
}
#endif /* CONFIG_SMC_KERNEL_CRYPTO */
diff --git a/security/smc/tf_crypto_digest.c b/security/smc/tf_crypto_digest.c
index 590b6c1..864615f 100644
--- a/security/smc/tf_crypto_digest.c
+++ b/security/smc/tf_crypto_digest.c
@@ -477,7 +477,7 @@ static bool tf_digest_hw_perform_dma(u8 *data, u32 nDataLength,
/*lock the DMA */
if (!mutex_trylock(&dev->sm.dma_mutex)) {
local_buf = dma_alloc_coherent(NULL, dev->dma_buffer_length,
- &local_buf_phys, GFP_KERNEL);
+ &local_buf_phys, GFP_ATOMIC);
if (local_buf == NULL) {
printk(KERN_ERR "SMC: DMA buffer is already taken "
"and %s could not allocate a temporary one\n",
diff --git a/security/smc/tf_device.c b/security/smc/tf_device.c
index fdcb5eb..97cf560 100644
--- a/security/smc/tf_device.c
+++ b/security/smc/tf_device.c
@@ -44,10 +44,6 @@
#include "s_version.h"
-#ifdef CONFIG_TF_ION
-extern struct ion_device *omap_ion_device;
-#endif
-
/*----------------------------------------------------------------------------
* Forward Declarations
*----------------------------------------------------------------------------*/
@@ -582,9 +578,9 @@ static long tf_device_ioctl(struct file *file, unsigned int ioctl_num,
/* Initialize ION connection */
if (connection->ion_client == NULL) {
connection->ion_client = ion_client_create(
- omap_ion_device,
+ zebra_ion_device,
(1 << ION_HEAP_TYPE_CARVEOUT),
- "smc");
+ "tf");
}
if (connection->ion_client == NULL) {
diff --git a/security/smc/tf_zebra.h b/security/smc/tf_zebra.h
index 23370b7..e67e95b 100644
--- a/security/smc/tf_zebra.h
+++ b/security/smc/tf_zebra.h
@@ -22,6 +22,11 @@
#include "tf_defs.h"
+#ifdef CONFIG_TF_ION
+extern struct ion_device *omap_ion_device;
+#define zebra_ion_device omap_ion_device
+#endif
+
int tf_ctrl_device_register(void);
int tf_start(struct tf_comm *comm,