diff options
author | Trusted Logic <smc_support@trusted-logic.com> | 2012-05-09 13:22:41 -0500 |
---|---|---|
committer | Dmytro Kedrovskyi <x0169235@ti.com> | 2012-06-12 19:39:53 +0300 |
commit | 9b0673eabf35cd5b7810276e826105178031fbf3 (patch) | |
tree | a1b9621fe301833d7f5b474c814531f56a8f074a /security/smc | |
parent | dfb7f3443f8e8428d1ee3a26ac4bd9a905ef0967 (diff) | |
download | kernel_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.h | 2 | ||||
-rw-r--r-- | security/smc/tf_comm.c | 31 | ||||
-rw-r--r-- | security/smc/tf_comm_mshield.c | 9 | ||||
-rw-r--r-- | security/smc/tf_conn.c | 10 | ||||
-rw-r--r-- | security/smc/tf_crypto_aes.c | 38 | ||||
-rw-r--r-- | security/smc/tf_crypto_digest.c | 2 | ||||
-rw-r--r-- | security/smc/tf_device.c | 8 | ||||
-rw-r--r-- | security/smc/tf_zebra.h | 5 |
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, |