diff options
author | Scott Long <scottl@nvidia.com> | 2014-01-29 17:48:10 -0800 |
---|---|---|
committer | Chris Johnson <cwj@nvidia.com> | 2014-02-03 19:44:34 -0800 |
commit | f56287b8dd4b0501f891e69d1af4d8770fa46e4b (patch) | |
tree | f2f13fc3dec20b44e643d48810cb17f4563cb4d2 /security | |
parent | e659ec0f0cac743f00dad4f21f9e3d8b200eac27 (diff) |
security: tlk_driver: add new storage support
The existing storage protocol support will remain enabled
until tlk can be switched over to the new protocol.
Bug 1397251
Change-Id: I7186774e6fd6072f8260780b82203ce5d9ddf820
Signed-off-by: Scott Long <scottl@nvidia.com>
Reviewed-on: http://git-master/r/361797
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Chris Johnson <cwj@nvidia.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/tlk_driver/ote_comms.c | 5 | ||||
-rw-r--r-- | security/tlk_driver/ote_device.c | 6 | ||||
-rw-r--r-- | security/tlk_driver/ote_fs.c | 84 | ||||
-rw-r--r-- | security/tlk_driver/ote_protocol.h | 16 |
4 files changed, 103 insertions, 8 deletions
diff --git a/security/tlk_driver/ote_comms.c b/security/tlk_driver/ote_comms.c index 19861adca5d0..eb9fc688e384 100644 --- a/security/tlk_driver/ote_comms.c +++ b/security/tlk_driver/ote_comms.c @@ -52,10 +52,8 @@ static struct te_shmem_desc *te_add_shmem_desc(void *buffer, size_t size, static int te_pin_mem_buffers(void *buffer, size_t size, struct tlk_context *context) { - - unsigned long pages = 0; struct te_shmem_desc *shmem_desc = NULL; - int ret = 0, nr_pages = 0; + int ret = 0; shmem_desc = te_add_shmem_desc(buffer, size, context); if (!shmem_desc) { @@ -107,7 +105,6 @@ static int te_setup_temp_buffers(struct te_request *request, static void te_del_shmem_desc(void *buffer, struct tlk_context *context) { struct te_shmem_desc *shmem_desc, *tmp_shmem_desc; - int i; list_for_each_entry_safe(shmem_desc, tmp_shmem_desc, &(context->shmem_alloc_list), list) { diff --git a/security/tlk_driver/ote_device.c b/security/tlk_driver/ote_device.c index 63c9a912e1aa..03fa1acc2129 100644 --- a/security/tlk_driver/ote_device.c +++ b/security/tlk_driver/ote_device.c @@ -423,10 +423,16 @@ static long tlk_device_ioctl(struct file *file, unsigned int ioctl_num, err = te_handle_fs_ioctl(file, ioctl_num, ioctl_param); break; + case TE_IOCTL_SS_NEW_REQ: + case TE_IOCTL_SS_REQ_COMPLETE: + err = te_handle_ss_ioctl(file, ioctl_num, ioctl_param); + break; + default: pr_err("%s: Invalid IOCTL (0x%x) id 0x%x max 0x%x\n", __func__, ioctl_num, _IOC_NR(ioctl_num), TE_IOCTL_MAX_NR); err = -EINVAL; + break; } return err; diff --git a/security/tlk_driver/ote_fs.c b/security/tlk_driver/ote_fs.c index 3ac9ebdb1e37..d398bebed9d2 100644 --- a/security/tlk_driver/ote_fs.c +++ b/security/tlk_driver/ote_fs.c @@ -45,11 +45,19 @@ static DECLARE_COMPLETION(req_ready); static DECLARE_COMPLETION(req_complete); static unsigned long secure_error; +static struct te_ss_op *ss_op_shmem; +static uint32_t ss_op_size; + static void indicate_complete(unsigned long ret) { tlk_generic_smc(TE_SMC_FS_OP_DONE, ret, 0); } +static void indicate_ss_op_complete(void) +{ + tlk_generic_smc(TE_SMC_SS_REQ_COMPLETE, 0, 0); +} + int te_handle_fs_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { @@ -132,6 +140,10 @@ int te_handle_fs_ioctl(struct file *file, unsigned int ioctl_num, /* signal the producer */ complete(&req_complete); break; + + default: + pr_err("copy_from_user failed for request\n"); + return -EINVAL; } return 0; @@ -197,7 +209,54 @@ void tlk_fdelete(const char *name) _te_fs_file_operation(name, NULL, 0, OTE_FILE_REQ_DELETE); } -static int __init tlk_fs_register_handlers(void) +int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num, + unsigned long ioctl_param) +{ + switch (ioctl_num) { + case TE_IOCTL_SS_NEW_REQ: + /* wait for a new request */ + if (wait_for_completion_interruptible(&req_ready)) + return -ENODATA; + + /* transfer pending request to daemon's buffer */ + if (copy_to_user((void __user *)ioctl_param, ss_op_shmem, + ss_op_size)) { + pr_err("copy_to_user failed for new request\n"); + return -EFAULT; + } + break; + + case TE_IOCTL_SS_REQ_COMPLETE: /* request complete */ + if (copy_from_user(ss_op_shmem, (void __user *)ioctl_param, + ss_op_size)) { + pr_err("copy_from_user failed for request\n"); + return -EFAULT; + } + + /* signal the producer */ + complete(&req_complete); + break; + } + + return 0; +} + +void tlk_ss_op(uint32_t size) +{ + /* store size of request */ + ss_op_size = size; + + /* signal consumer */ + complete(&req_ready); + + /* wait for the consumer's signal */ + wait_for_completion(&req_complete); + + /* signal completion to the secure world */ + indicate_ss_op_complete(); +} + +static int tlk_fs_register_handlers(void) { struct te_file_req_shmem *shmem_ptr; uint32_t smc_args[MAX_EXT_SMC_ARGS]; @@ -228,4 +287,25 @@ static int __init tlk_fs_register_handlers(void) return 0; } -arch_initcall(tlk_fs_register_handlers); +static int __init tlk_ss_init(void) +{ + dma_addr_t ss_op_shmem_dma; + + /* register legacy support */ + tlk_fs_register_handlers(); + + /* allocate shared memory buffer */ + ss_op_shmem = dma_alloc_coherent(NULL, sizeof(struct te_ss_op), + &ss_op_shmem_dma, GFP_KERNEL); + if (!ss_op_shmem) { + pr_err("%s: no memory available for fs operations\n", __func__); + return -ENOMEM; + } + + tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER, + (uint32_t)tlk_ss_op, (uint32_t)ss_op_shmem); + + return 0; +} + +arch_initcall(tlk_ss_init); diff --git a/security/tlk_driver/ote_protocol.h b/security/tlk_driver/ote_protocol.h index a27b83b6ea1f..f74e1734df7a 100644 --- a/security/tlk_driver/ote_protocol.h +++ b/security/tlk_driver/ote_protocol.h @@ -34,9 +34,13 @@ _IOR(TE_IOCTL_MAGIC_NUMBER, 0x17, struct te_file_req) #define TE_IOCTL_FILE_REQ_COMPLETE \ _IOWR(TE_IOCTL_MAGIC_NUMBER, 0x18, struct te_file_req) +#define TE_IOCTL_SS_NEW_REQ \ + _IOR(TE_IOCTL_MAGIC_NUMBER, 0x20, struct te_ss_op) +#define TE_IOCTL_SS_REQ_COMPLETE \ + _IOWR(TE_IOCTL_MAGIC_NUMBER, 0x21, struct te_ss_op) #define TE_IOCTL_MIN_NR _IOC_NR(TE_IOCTL_OPEN_CLIENT_SESSION) -#define TE_IOCTL_MAX_NR _IOC_NR(TE_IOCTL_FILE_REQ_COMPLETE) +#define TE_IOCTL_MAX_NR _IOC_NR(TE_IOCTL_SS_REQ_COMPLETE) /* shared buffer is 2 pages: 1st are requests, 2nd are params */ #define TE_CMD_DESC_MAX (PAGE_SIZE / sizeof(struct te_request)) @@ -95,7 +99,8 @@ enum { TE_SMC_NS_IRQ_DONE = 0x32000005, TE_SMC_FS_OP_DONE = 0x32000006, TE_SMC_INIT_LOGGER = 0x32000007, - + TE_SMC_SS_REGISTER_HANDLER = 0x32000008, + TE_SMC_SS_REQ_COMPLETE = 0x32000009, }; enum { @@ -218,6 +223,13 @@ struct te_file_req { int error; }; +#define SS_OP_MAX_DATA_SIZE 0x1000 +struct te_ss_op { + uint8_t data[SS_OP_MAX_DATA_SIZE]; +}; + +int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num, + unsigned long ioctl_param); int te_handle_fs_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param); void ote_print_logs(void); |