diff options
author | Jens Wiklander | 2016-10-21 02:23:24 -0500 |
---|---|---|
committer | Jérôme Forissier | 2017-10-05 04:16:04 -0500 |
commit | 27888d73d156d4862c07effce7c8c2455774768b (patch) | |
tree | 1d20d274c65eadf690f916824497534edf61c8c3 | |
parent | f761a27c454030131678a3c175fdf8876e95f59c (diff) | |
download | ti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.tar.gz ti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.tar.xz ti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.zip |
tee_client_api: register user memory
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Igor Opaniuk <igor.opaniuk@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r-- | libteec/include/linux/tee.h | 31 | ||||
-rw-r--r-- | libteec/src/tee_client_api.c | 106 | ||||
-rw-r--r-- | public/tee_client_api.h | 3 |
3 files changed, 113 insertions, 27 deletions
diff --git a/libteec/include/linux/tee.h b/libteec/include/linux/tee.h index 8f6c1a4e..f19b2b4c 100644 --- a/libteec/include/linux/tee.h +++ b/libteec/include/linux/tee.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define TEE_MAX_ARG_SIZE 1024 | 49 | #define TEE_MAX_ARG_SIZE 1024 |
50 | 50 | ||
51 | #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ | 51 | #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ |
52 | #define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */ | ||
52 | 53 | ||
53 | /* | 54 | /* |
54 | * TEE Implementation ID | 55 | * TEE Implementation ID |
@@ -145,6 +146,36 @@ struct tee_ioctl_shm_register_fd_data { | |||
145 | struct tee_ioctl_shm_register_fd_data) | 146 | struct tee_ioctl_shm_register_fd_data) |
146 | 147 | ||
147 | /** | 148 | /** |
149 | * struct tee_ioctl_shm_register_data - Shared memory register argument | ||
150 | * @addr: [in] Start address of shared memory to register | ||
151 | * @length: [in/out] Length of shared memory to register | ||
152 | * @flags: [in/out] Flags to/from registration. | ||
153 | * @id: [out] Identifier of the shared memory | ||
154 | * | ||
155 | * The flags field should currently be zero as input. Updated by the call | ||
156 | * with actual flags as defined by TEE_IOCTL_SHM_* above. | ||
157 | * This structure is used as argument for TEE_IOC_SHM_REGISTER below. | ||
158 | */ | ||
159 | struct tee_ioctl_shm_register_data { | ||
160 | __u64 addr; | ||
161 | __u64 length; | ||
162 | __u32 flags; | ||
163 | __s32 id; | ||
164 | }; | ||
165 | |||
166 | /** | ||
167 | * TEE_IOC_SHM_REGISTER - Register shared memory | ||
168 | * | ||
169 | * Registers shared memory between the user space process and secure OS. | ||
170 | * | ||
171 | * Returns a file descriptor on success or < 0 on failure | ||
172 | * | ||
173 | * The shared memory is unregisterred when the descriptor is closed. | ||
174 | */ | ||
175 | #define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \ | ||
176 | struct tee_ioctl_shm_register_data) | ||
177 | |||
178 | /** | ||
148 | * struct tee_ioctl_buf_data - Variable sized buffer | 179 | * struct tee_ioctl_buf_data - Variable sized buffer |
149 | * @buf_ptr: [in] A __user pointer to a buffer | 180 | * @buf_ptr: [in] A __user pointer to a buffer |
150 | * @buf_len: [in] Length of the buffer above | 181 | * @buf_len: [in] Length of the buffer above |
diff --git a/libteec/src/tee_client_api.c b/libteec/src/tee_client_api.c index f30dad53..698092b7 100644 --- a/libteec/src/tee_client_api.c +++ b/libteec/src/tee_client_api.c | |||
@@ -29,8 +29,8 @@ | |||
29 | #include <fcntl.h> | 29 | #include <fcntl.h> |
30 | #include <limits.h> | 30 | #include <limits.h> |
31 | #include <pthread.h> | 31 | #include <pthread.h> |
32 | #include <stdbool.h> | ||
33 | #include <stdio.h> | 32 | #include <stdio.h> |
33 | #include <stdlib.h> | ||
34 | #include <string.h> | 34 | #include <string.h> |
35 | #include <sys/ioctl.h> | 35 | #include <sys/ioctl.h> |
36 | #include <sys/mman.h> | 36 | #include <sys/mman.h> |
@@ -63,7 +63,8 @@ static void teec_mutex_unlock(pthread_mutex_t *mu) | |||
63 | pthread_mutex_unlock(mu); | 63 | pthread_mutex_unlock(mu); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int teec_open_dev(const char *devname, const char *capabilities) | 66 | static int teec_open_dev(const char *devname, const char *capabilities, |
67 | uint32_t *gen_caps) | ||
67 | { | 68 | { |
68 | struct tee_ioctl_version_data vers; | 69 | struct tee_ioctl_version_data vers; |
69 | int fd; | 70 | int fd; |
@@ -93,6 +94,7 @@ static int teec_open_dev(const char *devname, const char *capabilities) | |||
93 | } | 94 | } |
94 | } | 95 | } |
95 | 96 | ||
97 | *gen_caps = vers.gen_caps; | ||
96 | return fd; | 98 | return fd; |
97 | err: | 99 | err: |
98 | close(fd); | 100 | close(fd); |
@@ -113,6 +115,21 @@ static int teec_shm_alloc(int fd, size_t size, int *id) | |||
113 | return shm_fd; | 115 | return shm_fd; |
114 | } | 116 | } |
115 | 117 | ||
118 | static int teec_shm_register(int fd, void *buf, size_t size, int *id) | ||
119 | { | ||
120 | int shm_fd; | ||
121 | struct tee_ioctl_shm_register_data data; | ||
122 | |||
123 | memset(&data, 0, sizeof(data)); | ||
124 | data.addr = (uintptr_t)buf; | ||
125 | data.length = size; | ||
126 | shm_fd = ioctl(fd, TEE_IOC_SHM_REGISTER, &data); | ||
127 | if (shm_fd < 0) | ||
128 | return -1; | ||
129 | *id = data.id; | ||
130 | return shm_fd; | ||
131 | } | ||
132 | |||
116 | TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx) | 133 | TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx) |
117 | { | 134 | { |
118 | char devname[PATH_MAX]; | 135 | char devname[PATH_MAX]; |
@@ -123,10 +140,13 @@ TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx) | |||
123 | return TEEC_ERROR_BAD_PARAMETERS; | 140 | return TEEC_ERROR_BAD_PARAMETERS; |
124 | 141 | ||
125 | for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) { | 142 | for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) { |
143 | uint32_t gen_caps; | ||
144 | |||
126 | snprintf(devname, sizeof(devname), "/dev/tee%zu", n); | 145 | snprintf(devname, sizeof(devname), "/dev/tee%zu", n); |
127 | fd = teec_open_dev(devname, name); | 146 | fd = teec_open_dev(devname, name, &gen_caps); |
128 | if (fd >= 0) { | 147 | if (fd >= 0) { |
129 | ctx->fd = fd; | 148 | ctx->fd = fd; |
149 | ctx->reg_mem = gen_caps & TEE_GEN_CAP_REG_MEM; | ||
130 | return TEEC_SUCCESS; | 150 | return TEEC_SUCCESS; |
131 | } | 151 | } |
132 | } | 152 | } |
@@ -635,20 +655,29 @@ TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm) | |||
635 | s = shm->size; | 655 | s = shm->size; |
636 | if (!s) | 656 | if (!s) |
637 | s = 8; | 657 | s = 8; |
638 | 658 | if (ctx->reg_mem) { | |
639 | fd = teec_shm_alloc(ctx->fd, s, &shm->id); | 659 | fd = teec_shm_register(ctx->fd, shm->buffer, s, &shm->id); |
640 | if (fd < 0) | 660 | if (fd < 0) |
641 | return TEEC_ERROR_OUT_OF_MEMORY; | 661 | return TEEC_ERROR_OUT_OF_MEMORY; |
642 | 662 | shm->registered_fd = fd; | |
643 | shm->shadow_buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED, | 663 | shm->shadow_buffer = NULL; |
644 | fd, 0); | 664 | } else { |
645 | close(fd); | 665 | fd = teec_shm_alloc(ctx->fd, s, &shm->id); |
646 | if (shm->shadow_buffer == (void *)MAP_FAILED) { | 666 | if (fd < 0) |
647 | shm->id = -1; | 667 | return TEEC_ERROR_OUT_OF_MEMORY; |
648 | return TEEC_ERROR_OUT_OF_MEMORY; | 668 | |
669 | shm->shadow_buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, | ||
670 | MAP_SHARED, fd, 0); | ||
671 | close(fd); | ||
672 | if (shm->shadow_buffer == (void *)MAP_FAILED) { | ||
673 | shm->id = -1; | ||
674 | return TEEC_ERROR_OUT_OF_MEMORY; | ||
675 | } | ||
676 | shm->registered_fd = -1; | ||
649 | } | 677 | } |
678 | |||
650 | shm->alloced_size = s; | 679 | shm->alloced_size = s; |
651 | shm->registered_fd = -1; | 680 | shm->buffer_allocated = false; |
652 | return TEEC_SUCCESS; | 681 | return TEEC_SUCCESS; |
653 | } | 682 | } |
654 | 683 | ||
@@ -694,19 +723,36 @@ TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm) | |||
694 | if (!s) | 723 | if (!s) |
695 | s = 8; | 724 | s = 8; |
696 | 725 | ||
697 | fd = teec_shm_alloc(ctx->fd, s, &shm->id); | 726 | if (ctx->reg_mem) { |
698 | if (fd < 0) | 727 | shm->buffer = malloc(s); |
699 | return TEEC_ERROR_OUT_OF_MEMORY; | 728 | if (!shm->buffer) |
729 | return TEEC_ERROR_OUT_OF_MEMORY; | ||
700 | 730 | ||
701 | shm->buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | 731 | fd = teec_shm_register(ctx->fd, shm->buffer, s, &shm->id); |
702 | close(fd); | 732 | if (fd < 0) { |
703 | if (shm->buffer == (void *)MAP_FAILED) { | 733 | free(shm->buffer); |
704 | shm->id = -1; | 734 | shm->buffer = NULL; |
705 | return TEEC_ERROR_OUT_OF_MEMORY; | 735 | return TEEC_ERROR_OUT_OF_MEMORY; |
736 | } | ||
737 | shm->registered_fd = fd; | ||
738 | } else { | ||
739 | fd = teec_shm_alloc(ctx->fd, s, &shm->id); | ||
740 | if (fd < 0) | ||
741 | return TEEC_ERROR_OUT_OF_MEMORY; | ||
742 | |||
743 | shm->buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, | ||
744 | MAP_SHARED, fd, 0); | ||
745 | close(fd); | ||
746 | if (shm->buffer == (void *)MAP_FAILED) { | ||
747 | shm->id = -1; | ||
748 | return TEEC_ERROR_OUT_OF_MEMORY; | ||
749 | } | ||
750 | shm->registered_fd = -1; | ||
706 | } | 751 | } |
752 | |||
707 | shm->shadow_buffer = NULL; | 753 | shm->shadow_buffer = NULL; |
708 | shm->alloced_size = s; | 754 | shm->alloced_size = s; |
709 | shm->registered_fd = -1; | 755 | shm->buffer_allocated = true; |
710 | return TEEC_SUCCESS; | 756 | return TEEC_SUCCESS; |
711 | } | 757 | } |
712 | 758 | ||
@@ -717,13 +763,19 @@ void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shm) | |||
717 | 763 | ||
718 | if (shm->shadow_buffer) | 764 | if (shm->shadow_buffer) |
719 | munmap(shm->shadow_buffer, shm->alloced_size); | 765 | munmap(shm->shadow_buffer, shm->alloced_size); |
720 | else if (shm->buffer) | 766 | else if (shm->buffer) { |
721 | munmap(shm->buffer, shm->alloced_size); | 767 | if (shm->registered_fd >= 0) { |
722 | else if (shm->registered_fd >= 0) | 768 | if (shm->buffer_allocated) |
769 | free(shm->buffer); | ||
770 | close(shm->registered_fd); | ||
771 | } else | ||
772 | munmap(shm->buffer, shm->alloced_size); | ||
773 | } else if (shm->registered_fd >= 0) | ||
723 | close(shm->registered_fd); | 774 | close(shm->registered_fd); |
724 | 775 | ||
725 | shm->id = -1; | 776 | shm->id = -1; |
726 | shm->shadow_buffer = NULL; | 777 | shm->shadow_buffer = NULL; |
727 | shm->buffer = NULL; | 778 | shm->buffer = NULL; |
728 | shm->registered_fd = -1; | 779 | shm->registered_fd = -1; |
780 | shm->buffer_allocated = false; | ||
729 | } | 781 | } |
diff --git a/public/tee_client_api.h b/public/tee_client_api.h index a9d8a052..f37886df 100644 --- a/public/tee_client_api.h +++ b/public/tee_client_api.h | |||
@@ -35,6 +35,7 @@ extern "C" { | |||
35 | 35 | ||
36 | #include <stdint.h> | 36 | #include <stdint.h> |
37 | #include <stddef.h> | 37 | #include <stddef.h> |
38 | #include <stdbool.h> | ||
38 | #include <limits.h> | 39 | #include <limits.h> |
39 | 40 | ||
40 | /* | 41 | /* |
@@ -253,6 +254,7 @@ typedef uint32_t TEEC_Result; | |||
253 | typedef struct { | 254 | typedef struct { |
254 | /* Implementation defined */ | 255 | /* Implementation defined */ |
255 | int fd; | 256 | int fd; |
257 | bool reg_mem; | ||
256 | } TEEC_Context; | 258 | } TEEC_Context; |
257 | 259 | ||
258 | /** | 260 | /** |
@@ -294,6 +296,7 @@ typedef struct { | |||
294 | size_t alloced_size; | 296 | size_t alloced_size; |
295 | void *shadow_buffer; | 297 | void *shadow_buffer; |
296 | int registered_fd; | 298 | int registered_fd; |
299 | bool buffer_allocated; | ||
297 | } TEEC_SharedMemory; | 300 | } TEEC_SharedMemory; |
298 | 301 | ||
299 | /** | 302 | /** |