-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OP-TEE Benchmark #1365
OP-TEE Benchmark #1365
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
/* | ||
* Copyright (c) 2017, Linaro Limited | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright notice, | ||
* this list of conditions and the following disclaimer in the documentation | ||
* and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
#include <bench.h> | ||
#include <compiler.h> | ||
#include <kernel/misc.h> | ||
#include <kernel/mutex.h> | ||
#include <kernel/pseudo_ta.h> | ||
#include <malloc.h> | ||
#include <mm/core_memprot.h> | ||
#include <mm/tee_mm.h> | ||
#include <mm/tee_pager.h> | ||
#include <pta_benchmark.h> | ||
#include <string.h> | ||
#include <string_ext.h> | ||
#include <stdio.h> | ||
#include <trace.h> | ||
|
||
#define TA_NAME "benchmark.ta" | ||
|
||
struct tee_ts_global *bench_ts_global; | ||
static struct mutex bench_reg_mu = MUTEX_INITIALIZER; | ||
|
||
static TEE_Result rpc_reg_global_buf(uint64_t type, paddr_t phta, size_t size) | ||
{ | ||
struct optee_msg_param rpc_params; | ||
|
||
memset(&rpc_params, 0, sizeof(rpc_params)); | ||
rpc_params.attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; | ||
rpc_params.u.value.a = type; | ||
rpc_params.u.value.b = (uint64_t)phta; | ||
rpc_params.u.value.c = size; | ||
|
||
return thread_rpc_cmd(OPTEE_MSG_RPC_CMD_BENCH_REG, 1, &rpc_params); | ||
} | ||
|
||
static TEE_Result register_benchmark_memref(uint32_t type, | ||
TEE_Param p[TEE_NUM_PARAMS]) | ||
{ | ||
TEE_Result res; | ||
|
||
if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) || | ||
(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) { | ||
return TEE_ERROR_BAD_PARAMETERS; | ||
} | ||
|
||
/* | ||
* We accept only non-secure buffers, as we later perform | ||
* registration of this buffer in NS layers | ||
* (optee linux kmod/optee client) | ||
*/ | ||
if (!tee_vbuf_is_non_sec(p[0].memref.buffer, p[0].memref.size)) | ||
return TEE_ERROR_BAD_PARAMETERS; | ||
|
||
mutex_lock(&bench_reg_mu); | ||
|
||
/* Check if we have already registered buffer */ | ||
if (bench_ts_global) { | ||
EMSG("Timestamp buffer was already registered\n"); | ||
mutex_unlock(&bench_reg_mu); | ||
return TEE_ERROR_BAD_STATE; | ||
} | ||
|
||
DMSG("Registering timestamp buffer, addr = %p, paddr = %" PRIxPA "\n", | ||
p[0].memref.buffer, | ||
virt_to_phys(p[0].memref.buffer)); | ||
bench_ts_global = p[0].memref.buffer; | ||
|
||
mutex_unlock(&bench_reg_mu); | ||
|
||
/* Send back to the optee linux kernel module */ | ||
res = rpc_reg_global_buf(OPTEE_MSG_RPC_CMD_BENCH_REG_NEW, | ||
virt_to_phys((void *)bench_ts_global), | ||
sizeof(struct tee_ts_global) + | ||
sizeof(struct tee_ts_cpu_buf) * | ||
bench_ts_global->cores); | ||
|
||
return res; | ||
} | ||
|
||
static TEE_Result get_benchmark_memref(uint32_t type, | ||
TEE_Param p[TEE_NUM_PARAMS]) | ||
{ | ||
if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_VALUE_OUTPUT) || | ||
(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) { | ||
return TEE_ERROR_BAD_PARAMETERS; | ||
} | ||
|
||
mutex_lock(&bench_reg_mu); | ||
|
||
DMSG("Sending back timestamp buffer paddr = %p\n", | ||
(void *)virt_to_phys(bench_ts_global)); | ||
p[0].value.a = virt_to_phys(bench_ts_global); | ||
p[0].value.b = sizeof(struct tee_ts_global) + | ||
sizeof(struct tee_ts_cpu_buf) * bench_ts_global->cores; | ||
|
||
mutex_unlock(&bench_reg_mu); | ||
|
||
return TEE_SUCCESS; | ||
} | ||
|
||
static TEE_Result unregister_benchmark(uint32_t type, | ||
TEE_Param p[TEE_NUM_PARAMS] __unused) | ||
{ | ||
TEE_Result res; | ||
|
||
if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) || | ||
(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) { | ||
return TEE_ERROR_BAD_PARAMETERS; | ||
} | ||
mutex_lock(&bench_reg_mu); | ||
|
||
DMSG("Unregistering benchmark, timestamp buffer paddr = %p\n", | ||
(void *)virt_to_phys(bench_ts_global)); | ||
bench_ts_global = NULL; | ||
|
||
mutex_unlock(&bench_reg_mu); | ||
|
||
res = rpc_reg_global_buf(OPTEE_MSG_RPC_CMD_BENCH_REG_DEL, 0, 0); | ||
|
||
return res; | ||
} | ||
|
||
static TEE_Result invoke_command(void *session_ctx __unused, | ||
uint32_t cmd_id, uint32_t param_types, | ||
TEE_Param params[TEE_NUM_PARAMS]) | ||
{ | ||
switch (cmd_id) { | ||
case BENCHMARK_CMD_REGISTER_MEMREF: | ||
return register_benchmark_memref(param_types, params); | ||
case BENCHMARK_CMD_GET_MEMREF: | ||
return get_benchmark_memref(param_types, params); | ||
case BENCHMARK_CMD_UNREGISTER: | ||
return unregister_benchmark(param_types, params); | ||
default: | ||
break; | ||
} | ||
|
||
return TEE_ERROR_BAD_PARAMETERS; | ||
} | ||
|
||
pseudo_ta_register(.uuid = BENCHMARK_UUID, .name = TA_NAME, | ||
.flags = PTA_DEFAULT_FLAGS, | ||
.invoke_command_entry_point = invoke_command); | ||
|
||
void bm_timestamp(void) | ||
{ | ||
struct tee_ts_cpu_buf *cpu_buf; | ||
struct tee_time_st ts_data; | ||
uint64_t ts_i; | ||
void *ret_addr; | ||
uint32_t cur_cpu; | ||
uint32_t exceptions; | ||
|
||
if (!bench_ts_global) | ||
return; | ||
|
||
exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); | ||
cur_cpu = get_core_pos(); | ||
|
||
if (cur_cpu >= bench_ts_global->cores) { | ||
thread_unmask_exceptions(exceptions); | ||
return; | ||
} | ||
|
||
ret_addr = __builtin_return_address(0); | ||
|
||
cpu_buf = &bench_ts_global->cpu_buf[cur_cpu]; | ||
ts_i = cpu_buf->head++; | ||
ts_data.cnt = read_pmu_ccnt() * TEE_BENCH_DIVIDER; | ||
ts_data.addr = (uintptr_t)ret_addr; | ||
ts_data.src = TEE_BENCH_CORE; | ||
cpu_buf->stamps[ts_i & TEE_BENCH_MAX_MASK] = ts_data; | ||
|
||
thread_unmask_exceptions(exceptions); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
*/ | ||
|
||
#include <assert.h> | ||
#include <bench.h> | ||
#include <compiler.h> | ||
#include <initcall.h> | ||
#include <kernel/panic.h> | ||
|
@@ -286,6 +287,8 @@ static void entry_invoke_command(struct thread_smc_args *smc_args, | |
struct tee_ta_session *s; | ||
struct tee_ta_param param; | ||
|
||
bm_timestamp(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a known ID on which REE gets comprehensive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. saving There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the PC gives a clear view of trace point when rendering the output data to a human readable format, then it is fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's going to be mapped to specific file:line and function (the same as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is OK as it is for now. |
||
|
||
res = copy_in_params(arg->params, num_params, ¶m); | ||
if (res != TEE_SUCCESS) | ||
goto out; | ||
|
@@ -299,6 +302,8 @@ static void entry_invoke_command(struct thread_smc_args *smc_args, | |
res = tee_ta_invoke_command(&err_orig, s, NSAPP_IDENTITY, | ||
TEE_TIMEOUT_INFINITE, arg->func, ¶m); | ||
|
||
bm_timestamp(); | ||
|
||
tee_ta_put_session(s); | ||
|
||
copy_out_param(¶m, num_params, arg->params); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2017, Linaro Limited | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright notice, | ||
* this list of conditions and the following disclaimer in the documentation | ||
* and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#ifndef BENCH_H | ||
#define BENCH_H | ||
|
||
#include <inttypes.h> | ||
#include <mm/core_memprot.h> | ||
#include <mm/core_mmu.h> | ||
#include <optee_msg.h> | ||
|
||
/* | ||
* Cycle count divider is enabled (in PMCR), | ||
* CCNT value is incremented every 64th clock cycle | ||
*/ | ||
#define TEE_BENCH_DIVIDER 64 | ||
|
||
/* Max amount of timestamps per buffer */ | ||
#define TEE_BENCH_MAX_STAMPS 32 | ||
#define TEE_BENCH_MAX_MASK (TEE_BENCH_MAX_STAMPS - 1) | ||
|
||
#define OPTEE_MSG_RPC_CMD_BENCH_REG_NEW 0 | ||
#define OPTEE_MSG_RPC_CMD_BENCH_REG_DEL 1 | ||
|
||
/* OP-TEE susbsystems ids */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I've started look into the PR in optee_os, but if this isn't a shared h-file (which I suspect it is), then we should maybe consider remove the ones not in use in optee_os. I'll update this comment when/if I've reviewed the other PRs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each rep(besides |
||
#define TEE_BENCH_CLIENT 0x10000000 | ||
#define TEE_BENCH_KMOD 0x20000000 | ||
#define TEE_BENCH_CORE 0x30000000 | ||
#define TEE_BENCH_UTEE 0x40000000 | ||
#define TEE_BENCH_DUMB_TA 0xF0000001 | ||
|
||
/* storing timestamp */ | ||
struct tee_time_st { | ||
uint64_t cnt; /* stores value from CNTPCT register */ | ||
uint64_t addr; /* stores value from program counter register */ | ||
uint64_t src; /* OP-TEE subsystem id */ | ||
}; | ||
|
||
/* per-cpu circular buffer for timestamps */ | ||
struct tee_ts_cpu_buf { | ||
uint64_t head; | ||
uint64_t tail; | ||
struct tee_time_st stamps[TEE_BENCH_MAX_STAMPS]; | ||
}; | ||
|
||
/* memory layout for shared memory, where timestamps will be stored */ | ||
struct tee_ts_global { | ||
uint64_t cores; | ||
struct tee_ts_cpu_buf cpu_buf[]; | ||
}; | ||
|
||
#ifdef CFG_TEE_BENCHMARK | ||
void bm_timestamp(void); | ||
#else | ||
static inline void bm_timestamp(void) {} | ||
#endif /* CFG_TEE_BENCHMARK */ | ||
|
||
#endif /* BENCH_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should check
p[0].memref.buffer
is mapped non-secure (case secure client) ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the client is secure, the buffer virtual address is likely to be temporary (to this TA invocation). Core should get the paddr and gets it core mapping to get a reliable virtual address for the buffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etienne-lms II didn't get it. Could you please provide any example of secure client case?
Or you mean TA-to-TA calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a TA invokes your pTA, the memref parameters can be SHM references or secure memory reference (specific case when TA use a memref parameter on a TA private buffer).
As we expect here a SHM buffer (later RPC to tee-supplicant), maybe you can only check
tee_pbuf_is_non_sec(p[0].memref.buffer, p[0].memref.size)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added check