diff options
author | Pascal Brand <pascal.brand@st.com> | 2015-02-03 13:45:20 +0100 |
---|---|---|
committer | Pascal Brand <pascal.brand@st.com> | 2015-02-12 09:47:42 +0100 |
commit | fa530828cafeb20aa384d4abb2b76c1fe6fab614 (patch) | |
tree | 07b164d2e59ac9473cc9ac78e65a5ca13165ce21 | |
parent | db5f4ae461cebc9d1d119d53aaa7ccd8ff7088d0 (diff) |
Internal API extension on Cache Operations
Following extensions are introduced:
- TEE_CacheClean()
- TEE_CacheFlush()
- TEE_CacheInvalidate()
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Tested-by: Pascal Brand <pascal.brand@linaro.org> (STM platform)
Signed-off-by: Pascal Brand <pascal.brand@st.com>
-rw-r--r-- | core/arch/arm32/kernel/tee_ta_manager.c | 56 | ||||
-rw-r--r-- | core/arch/arm32/plat-stm/conf.mk | 1 | ||||
-rw-r--r-- | core/arch/arm32/tee/arch_svc.c | 1 | ||||
-rw-r--r-- | core/include/kernel/tee_misc.h | 4 | ||||
-rw-r--r-- | core/include/kernel/tee_ta_manager.h | 8 | ||||
-rw-r--r-- | core/include/tee/tee_svc.h | 7 | ||||
-rw-r--r-- | core/tee/tee_svc.c | 18 | ||||
-rw-r--r-- | documentation/extensions/extensions.md | 31 | ||||
-rw-r--r-- | lib/libutee/arch/arm32/utee_syscalls_asm.S | 2 | ||||
-rw-r--r-- | lib/libutee/include/tee_internal_api_extensions.h | 18 | ||||
-rw-r--r-- | lib/libutee/include/tee_syscall_numbers.h | 3 | ||||
-rw-r--r-- | lib/libutee/include/utee_syscalls.h | 3 | ||||
-rw-r--r-- | lib/libutee/include/utee_types.h | 11 | ||||
-rw-r--r-- | lib/libutee/tee_api.c | 15 |
14 files changed, 170 insertions, 8 deletions
diff --git a/core/arch/arm32/kernel/tee_ta_manager.c b/core/arch/arm32/kernel/tee_ta_manager.c index e495585..2dadb11 100644 --- a/core/arch/arm32/kernel/tee_ta_manager.c +++ b/core/arch/arm32/kernel/tee_ta_manager.c @@ -61,8 +61,8 @@ #include <kernel/tee_kta_trace.h> #include <kernel/trace_ta.h> - -/* Use this invalid ID for a static TA, since +/* + * Use this invalid ID for a static TA, since * session is not needed for calling static TA. */ #define TEE_SESSION_ID_STATIC_TA 0xFFFFFFFF @@ -698,7 +698,7 @@ static TEE_Result tee_ta_param_pa2va(struct tee_ta_session *sess, case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: if (core_pa2va - ((uint32_t) param->params[n].memref.buffer, &va)) + ((uint32_t)param->params[n].memref.buffer, &va)) return TEE_ERROR_BAD_PARAMETERS; param->params[n].memref.buffer = va; break; @@ -711,7 +711,6 @@ static TEE_Result tee_ta_param_pa2va(struct tee_ta_session *sess, return TEE_SUCCESS; } - static void tee_ta_set_invoke_timeout(struct tee_ta_session *sess, uint32_t cancel_req_to) { @@ -1543,6 +1542,55 @@ TEE_Result tee_ta_verify_session_pointer(struct tee_ta_session *sess, } /* + * tee_uta_cache_operation - dynamic cache clean/inval request from a TA + */ +#ifdef CFG_CACHE_API +TEE_Result tee_uta_cache_operation(struct tee_ta_session *sess, + enum utee_cache_operation op, + void *va, size_t len) +{ + TEE_Result ret; + paddr_t pa = 0; + int l1op, l2op; + + if ((sess->ctx->flags & TA_FLAG_CACHE_MAINTENANCE) == 0) + return TEE_ERROR_NOT_SUPPORTED; + + ret = tee_mmu_check_access_rights(sess->ctx, + TEE_MEMORY_ACCESS_WRITE, (tee_uaddr_t)va, len); + if (ret != TEE_SUCCESS) + return TEE_ERROR_ACCESS_DENIED; + + ret = tee_mmu_user_va2pa(sess->ctx, va, &pa); + if (ret != TEE_SUCCESS) + return TEE_ERROR_ACCESS_DENIED; + + switch (op) { + case TEE_CACHEFLUSH: + l1op = DCACHE_AREA_CLEAN_INV; + l2op = L2CACHE_AREA_CLEAN_INV; + break; + case TEE_CACHECLEAN: + l1op = DCACHE_AREA_CLEAN; + l2op = L2CACHE_AREA_CLEAN; + break; + case TEE_CACHEINVALIDATE: + l1op = DCACHE_INVALIDATE; + l2op = L2CACHE_INVALIDATE; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + ret = cache_maintenance_l1(l1op, va, len); + if (ret != TEE_SUCCESS) + return ret; + + return cache_maintenance_l2(l2op, pa, len); +} +#endif + +/* * dump_state - Display TA state as an error log. */ static void dump_state(struct tee_ta_ctx *ctx) diff --git a/core/arch/arm32/plat-stm/conf.mk b/core/arch/arm32/plat-stm/conf.mk index f9ce6e6..7453268 100644 --- a/core/arch/arm32/plat-stm/conf.mk +++ b/core/arch/arm32/plat-stm/conf.mk @@ -14,6 +14,7 @@ core-platform-subdirs += \ libutil_with_isoc := y WITH_PL310 := y WITH_SECURE_TIME_SOURCE_REE := y +CFG_CACHE_API := y include mk/config.mk include $(platform-dir)/system_config.in diff --git a/core/arch/arm32/tee/arch_svc.c b/core/arch/arm32/tee/arch_svc.c index 7d626b9..739fde6 100644 --- a/core/arch/arm32/tee/arch_svc.c +++ b/core/arch/arm32/tee/arch_svc.c @@ -112,6 +112,7 @@ static const tee_svc_func tee_svc_syscall_table[] = { (tee_svc_func)tee_svc_se_channel_get_select_resp, (tee_svc_func)tee_svc_se_channel_transmit, (tee_svc_func)tee_svc_se_channel_close, + (tee_svc_func)tee_svc_cache_operation, }; void tee_svc_handler(struct thread_svc_regs *regs) diff --git a/core/include/kernel/tee_misc.h b/core/include/kernel/tee_misc.h index f2ffc05..ce7d52d 100644 --- a/core/include/kernel/tee_misc.h +++ b/core/include/kernel/tee_misc.h @@ -54,8 +54,8 @@ uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen); * * core_is_buffer_inside() - return true if buffer is inside memory area * core_is_buffer_outside() - return true if buffer is outside area - * core_is_buffer_over() - return true if buffer overlaps area - + * core_is_buffer_intersect() - return true if buffer overlaps area + * * Warning: core_is_buffer_inside(x,x,x,x)==false does NOT mean * core_is_buffer_outside(x,x,x,x)==true. * diff --git a/core/include/kernel/tee_ta_manager.h b/core/include/kernel/tee_ta_manager.h index 709ed6a..253f645 100644 --- a/core/include/kernel/tee_ta_manager.h +++ b/core/include/kernel/tee_ta_manager.h @@ -35,6 +35,7 @@ #include "tee_ta.h" #include <kernel/kta_types.h> #include "tee_ta_manager_unpg.h" +#include "utee_types.h" /*----------------------------------------------------------------------------- * Initializes virtual memory management by reserving virtual memory for @@ -101,8 +102,13 @@ TEE_Result tee_ta_verify_session_pointer(struct tee_ta_session *sess, *open_sessions); int tee_ta_set_trace_level(int level); - void tee_ta_dump_current(void); void tee_ta_dump_all(void); +#ifdef CFG_CACHE_API +TEE_Result tee_uta_cache_operation(struct tee_ta_session *s, + enum utee_cache_operation op, + void *va, size_t len); +#endif + #endif diff --git a/core/include/tee/tee_svc.h b/core/include/tee/tee_svc.h index 74228f1..fa38af1 100644 --- a/core/include/tee/tee_svc.h +++ b/core/include/tee/tee_svc.h @@ -87,6 +87,13 @@ TEE_Result tee_svc_wait(uint32_t timeout); TEE_Result tee_svc_get_time(enum utee_time_category cat, TEE_Time *time); TEE_Result tee_svc_set_ta_time(const TEE_Time *time); +#ifdef CFG_CACHE_API +TEE_Result tee_svc_cache_operation(void *va, size_t len, + enum utee_cache_operation op); +#else +#define tee_svc_cache_operation tee_svc_not_supported +#endif + void tee_svc_trace_syscall(int num); diff --git a/core/tee/tee_svc.c b/core/tee/tee_svc.c index 53a3f3a..93177d0 100644 --- a/core/tee/tee_svc.c +++ b/core/tee/tee_svc.c @@ -825,3 +825,21 @@ TEE_Result tee_svc_set_ta_time(const TEE_Time *mytime) return tee_time_set_ta_time((const void *)&s->ctx->head->uuid, &t); } + +#ifdef CFG_CACHE_API +TEE_Result tee_svc_cache_operation(void *va, size_t len, + enum utee_cache_operation op) +{ + TEE_Result res; + struct tee_ta_session *s = NULL; + + res = tee_ta_get_current_session(&s); + if (res != TEE_SUCCESS) + return res; + + if ((s->ctx->flags & TA_FLAG_CACHE_MAINTENANCE) == 0) + return TEE_ERROR_NOT_SUPPORTED; + + return tee_uta_cache_operation(s, op, va, len); +} +#endif diff --git a/documentation/extensions/extensions.md b/documentation/extensions/extensions.md new file mode 100644 index 0000000..b4b6444 --- /dev/null +++ b/documentation/extensions/extensions.md @@ -0,0 +1,31 @@ +# General Extensions to the GlobalPlatform TEE Internal API + +This document describes the OP-TEE extensions introduced with respect to the GlobalPlatform TEE API Specifications v1.0. + +Specific extensions documentation are part of: +* Cryptographic Extensions + * [Concatenation Key Derivation](crypto_concat_kdf.md) + * [HMAC Key Derivation](crypto_hkdf.md) + * [Public-Key Key Derivation](crypto_pbkdf2.md) + + +# Cache Maintenance Support +Following functions have been introduced in order to operate with cache: + + TEE_Result TEE_CacheClean(char *buf, size_t len); + TEE_Result TEE_CacheFlush(char *buf, size_t len); + TEE_Result TEE_CacheInvalidate(char *buf, size_t len); + +These functions are available to any Trusted Application defined with the flag TA_FLAG_CACHE_MAINTENANCE sets on. When not set, each function returns the error code TEE_ERROR_NOT_SUPPORTED. + +Within these extensions, a Trusted Application is able to operate on the data cache, with the following specification: + +Function | Description +:---------------------|:---------- +TEE_CacheClean() | Write back to memory any dirty data cache lines. The line is marked as not dirty. The valid bit is unchanged +TEE_CacheFlush() | Purges any valid data cache lines. Any dirty cache lines are first written back to memory, then the cache line is invalidated. +TEE_CacheInvalidate() | Invalidate any valid data cache lines. Any dirty line are not written back to memory. + +In the following 2 cases, the error code TEE_ERROR_ACCESS_DENIED is returned: +* the memory range has not the write access, that is TEE_MEMORY_ACCESS_WRITE is not set. +* the memory is not a User Space memory diff --git a/lib/libutee/arch/arm32/utee_syscalls_asm.S b/lib/libutee/arch/arm32/utee_syscalls_asm.S index 679d420..a13e737 100644 --- a/lib/libutee/arch/arm32/utee_syscalls_asm.S +++ b/lib/libutee/arch/arm32/utee_syscalls_asm.S @@ -216,3 +216,5 @@ UTEE_SYSCALL utee_se_channel_close, \ TEE_SCN_SE_CHANNEL_CLOSE, 1 + + UTEE_SYSCALL utee_cache_operation, TEE_SCN_CACHE_OPERATION, 3 diff --git a/lib/libutee/include/tee_internal_api_extensions.h b/lib/libutee/include/tee_internal_api_extensions.h index 36b0ed3..0bf3cdc 100644 --- a/lib/libutee/include/tee_internal_api_extensions.h +++ b/lib/libutee/include/tee_internal_api_extensions.h @@ -31,6 +31,7 @@ /* trace support */ #include <trace.h> #include <stdio.h> +#include <tee_api_types.h> /* * User mem module @@ -41,4 +42,21 @@ size_t tee_user_mem_check_heap(void); /* Hint implementation defines */ #define TEE_USER_MEM_HINT_NO_FILL_ZERO 0x80000000 +/* + * Cache maintenance support (TA requires the CACHE_MAINTENANCE property) + * + * TEE_CacheClean() Write back to memory any dirty data cache lines. The line + * is marked as not dirty. The valid bit is unchanged. + * + * TEE_CacheFlush() Purges any valid data cache lines. Any dirty cache lines + * are first written back to memory, then the cache line is + * invalidated. + * + * TEE_CacheInvalidate() Invalidate any valid data cache lines. Any dirty line + * are not written back to memory. + */ +TEE_Result TEE_CacheClean(char *buf, size_t len); +TEE_Result TEE_CacheFlush(char *buf, size_t len); +TEE_Result TEE_CacheInvalidate(char *buf, size_t len); + #endif diff --git a/lib/libutee/include/tee_syscall_numbers.h b/lib/libutee/include/tee_syscall_numbers.h index 6e86351..922323d 100644 --- a/lib/libutee/include/tee_syscall_numbers.h +++ b/lib/libutee/include/tee_syscall_numbers.h @@ -99,8 +99,9 @@ #define TEE_SCN_SE_CHANNEL_GET_SELECT_RESP 68 #define TEE_SCN_SE_CHANNEL_TRANSMIT 69 #define TEE_SCN_SE_CHANNEL_CLOSE 70 +#define TEE_SCN_CACHE_OPERATION 71 -#define TEE_SCN_MAX 70 +#define TEE_SCN_MAX 71 /* Maximum number of allowed arguments for a syscall */ #define TEE_SVC_MAX_ARGS 10 diff --git a/lib/libutee/include/utee_syscalls.h b/lib/libutee/include/utee_syscalls.h index 8a1ca6d..84a14d2 100644 --- a/lib/libutee/include/utee_syscalls.h +++ b/lib/libutee/include/utee_syscalls.h @@ -229,4 +229,7 @@ TEE_Result utee_se_channel_transmit(TEE_SEChannelHandle c, TEE_Result utee_se_channel_close(TEE_SEChannelHandle c); +TEE_Result utee_cache_operation(void *va, size_t l, + enum utee_cache_operation op); + #endif /* UTEE_SYSCALLS_H */ diff --git a/lib/libutee/include/utee_types.h b/lib/libutee/include/utee_types.h index 47dbfc5..315d15b 100644 --- a/lib/libutee/include/utee_types.h +++ b/lib/libutee/include/utee_types.h @@ -44,4 +44,15 @@ enum utee_time_category { UTEE_TIME_CAT_REE }; +/* + * Cache operation types. + * Used when extensions TEE_CacheClean() / TEE_CacheFlush() / + * TEE_CacheInvalidate() are used + */ +enum utee_cache_operation { + TEE_CACHECLEAN = 0, + TEE_CACHEFLUSH, + TEE_CACHEINVALIDATE, +}; + #endif /* UTEE_TYPES_H */ diff --git a/lib/libutee/tee_api.c b/lib/libutee/tee_api.c index af64547..9f9f03a 100644 --- a/lib/libutee/tee_api.c +++ b/lib/libutee/tee_api.c @@ -221,3 +221,18 @@ void TEE_Free(void *buffer) { tee_user_mem_free(buffer); } + +/* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ +TEE_Result TEE_CacheClean(char *buf, size_t len) +{ + return utee_cache_operation(buf, len, TEE_CACHECLEAN); +} +TEE_Result TEE_CacheFlush(char *buf, size_t len) +{ + return utee_cache_operation(buf, len, TEE_CACHEFLUSH); +} + +TEE_Result TEE_CacheInvalidate(char *buf, size_t len) +{ + return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); +} |