aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPascal Brand <pascal.brand@st.com>2015-02-03 13:45:20 +0100
committerPascal Brand <pascal.brand@st.com>2015-02-12 09:47:42 +0100
commitfa530828cafeb20aa384d4abb2b76c1fe6fab614 (patch)
tree07b164d2e59ac9473cc9ac78e65a5ca13165ce21
parentdb5f4ae461cebc9d1d119d53aaa7ccd8ff7088d0 (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.c56
-rw-r--r--core/arch/arm32/plat-stm/conf.mk1
-rw-r--r--core/arch/arm32/tee/arch_svc.c1
-rw-r--r--core/include/kernel/tee_misc.h4
-rw-r--r--core/include/kernel/tee_ta_manager.h8
-rw-r--r--core/include/tee/tee_svc.h7
-rw-r--r--core/tee/tee_svc.c18
-rw-r--r--documentation/extensions/extensions.md31
-rw-r--r--lib/libutee/arch/arm32/utee_syscalls_asm.S2
-rw-r--r--lib/libutee/include/tee_internal_api_extensions.h18
-rw-r--r--lib/libutee/include/tee_syscall_numbers.h3
-rw-r--r--lib/libutee/include/utee_syscalls.h3
-rw-r--r--lib/libutee/include/utee_types.h11
-rw-r--r--lib/libutee/tee_api.c15
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);
+}