From ea7bc7d4d306e2bd36345c23687bf637efe5852b Mon Sep 17 00:00:00 2001 From: Kim Mankyum Date: Thu, 8 Nov 2018 07:59:30 +0900 Subject: [PATCH] [RAMEN9610-10541][9610] gud: Update kinibi410A V003 Change-Id: Id55130f557a5a964b1e2968eb46e424186ce7f2a Signed-off-by: Kim Mankyum --- drivers/gud/gud-exynos9610/Kconfig | 1 + drivers/gud/gud-exynos9610/Makefile | 1 + .../gud/gud-exynos9610/MobiCoreDriver/admin.c | 31 +++ .../gud-exynos9610/MobiCoreDriver/build_tag.h | 4 +- .../gud-exynos9610/MobiCoreDriver/client.c | 49 ++++- .../gud-exynos9610/MobiCoreDriver/fastcall.c | 36 +--- .../gud-exynos9610/MobiCoreDriver/fastcall.h | 1 - .../gud/gud-exynos9610/MobiCoreDriver/iwp.c | 14 +- .../gud-exynos9610/MobiCoreDriver/logging.c | 39 ++-- .../gud/gud-exynos9610/MobiCoreDriver/main.c | 52 +---- .../gud-exynos9610/MobiCoreDriver/mci/mcifc.h | 6 +- .../MobiCoreDriver/mci/mcimcp.h | 30 ++- .../gud/gud-exynos9610/MobiCoreDriver/mcp.c | 15 ++ .../gud/gud-exynos9610/MobiCoreDriver/mcp.h | 1 + .../gud/gud-exynos9610/MobiCoreDriver/mmu.c | 26 ++- .../gud/gud-exynos9610/MobiCoreDriver/nq.c | 194 ++---------------- .../gud-exynos9610/MobiCoreDriver/platform.h | 4 +- .../MobiCoreDriver/public/mc_admin.h | 2 + .../MobiCoreDriver/public/mc_linux_api.h | 30 --- .../gud-exynos9610/MobiCoreDriver/session.c | 26 ++- .../MobiCoreDriver/teeclientapi.c | 2 +- .../gud/gud-exynos9610/MobiCoreDriver/user.c | 5 +- .../gud-exynos9610/MobiCoreDriver/xen_fe.c | 14 ++ drivers/gud/gud-exynos9610/TlcTui/build_tag.h | 4 +- drivers/gud/gud-exynos9610/TlcTui/main.c | 9 + .../gud-exynos9610/TlcTui/public/tui_ioctl.h | 13 ++ drivers/gud/gud-exynos9610/TlcTui/tlcTui.c | 5 +- 27 files changed, 283 insertions(+), 331 deletions(-) delete mode 100755 drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_linux_api.h diff --git a/drivers/gud/gud-exynos9610/Kconfig b/drivers/gud/gud-exynos9610/Kconfig index 7827a98f8ea4..d141aeb7433f 100755 --- a/drivers/gud/gud-exynos9610/Kconfig +++ b/drivers/gud/gud-exynos9610/Kconfig @@ -35,5 +35,6 @@ config TRUSTONIC_TRUSTED_UI_FB_BLANK ---help--- Blank the framebuffer before starting a TUI session +#ExySp source "drivers/gud/gud-exynos9610/sec-os-ctrl/Kconfig" source "drivers/gud/gud-exynos9610/sec-os-booster/Kconfig" diff --git a/drivers/gud/gud-exynos9610/Makefile b/drivers/gud/gud-exynos9610/Makefile index a4c666994b6c..70d99b90a911 100755 --- a/drivers/gud/gud-exynos9610/Makefile +++ b/drivers/gud/gud-exynos9610/Makefile @@ -17,5 +17,6 @@ obj-$(CONFIG_TRUSTONIC_TEE) := MobiCoreDriver/ obj-$(CONFIG_TRUSTONIC_TRUSTED_UI) += TlcTui/ +#ExySp obj-$(CONFIG_SECURE_OS_CONTROL) += sec-os-ctrl/ obj-$(CONFIG_SECURE_OS_BOOSTER_API) += sec-os-booster/ diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/admin.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/admin.c index 022ea273b051..2ead5ee60ad7 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/admin.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/admin.c @@ -798,6 +798,26 @@ static inline int load_check(struct mc_admin_load_info *info) return ret; } +static inline int load_key_so(struct mc_admin_load_info *key_so) +{ + struct tee_mmu *mmu; + struct mcp_buffer_map map; + struct mc_ioctl_buffer buf; + int ret; + + buf.va = (uintptr_t)key_so->address; + buf.len = key_so->length; + buf.flags = MC_IO_MAP_INPUT; + mmu = tee_mmu_create(current->mm, &buf); + if (IS_ERR(mmu)) + return PTR_ERR(mmu); + + tee_mmu_buffer(mmu, &map); + ret = mcp_load_key_so(key_so->address, &map); + tee_mmu_put(mmu); + return ret; +} + static ssize_t admin_write(struct file *file, const char __user *user, size_t len, loff_t *off) { @@ -1019,6 +1039,17 @@ static long admin_ioctl(struct file *file, unsigned int cmd, ret = load_check(&info); break; } + case MC_ADMIN_IO_LOAD_KEY_SO: { + struct mc_admin_load_info info; + + if (copy_from_user(&info, uarg, sizeof(info))) { + ret = -EFAULT; + break; + } + + ret = load_key_so(&info); + break; + } default: ret = -ENOIOCTLCMD; } diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/build_tag.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/build_tag.h index d457b3511533..eefa20629307 100644 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/build_tag.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/build_tag.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 TRUSTONIC LIMITED + * Copyright (c) 2013-2018 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -13,5 +13,5 @@ */ #ifndef MOBICORE_COMPONENT_BUILD_TAG #define MOBICORE_COMPONENT_BUILD_TAG \ - "t-base-Exynos-Android-410a-v001-20180329_190510_46723_76543" + "t-base-Exynos-Android-410a-V003-20180920_200500_55985_85552" #endif diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/client.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/client.c index e94a54dcb917..9513d92ef53f 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/client.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/client.c @@ -50,6 +50,8 @@ struct tee_client { struct mutex sessions_lock; /* sessions list + closing */ /* Client lock for quick WSMs and operations changes */ struct mutex quick_lock; + /* Client lock for CWSMs release functions */ + struct mutex cwsm_release_lock; /* List of WSMs for a client */ struct list_head cwsms; /* List of GP operation for a client */ @@ -363,14 +365,18 @@ void client_get(struct tee_client *client) void client_put_cwsm_sva(struct tee_client *client, u32 sva) { - struct cwsm *cwsm = cwsm_find_by_sva(client, sva); + struct cwsm *cwsm; + mutex_lock(&client->cwsm_release_lock); + cwsm = cwsm_find_by_sva(client, sva); if (!cwsm) - return; + goto end; - /* Release reference taken by cwsm_find */ + /* Release reference taken by cwsm_find_by_sva */ cwsm_put(cwsm); cwsm_put(cwsm); +end: + mutex_unlock(&client->cwsm_release_lock); } /* @@ -398,6 +404,7 @@ struct tee_client *client_create(bool is_from_kernel) mutex_init(&client->sessions_lock); INIT_LIST_HEAD(&client->list); mutex_init(&client->quick_lock); + mutex_init(&client->cwsm_release_lock); INIT_LIST_HEAD(&client->cwsms); INIT_LIST_HEAD(&client->operations); /* Add client to list of clients */ @@ -863,6 +870,11 @@ int client_gp_register_shared_mem(struct tee_client *client, { struct cwsm *cwsm = NULL; + if (memref->size > BUFFER_LENGTH_MAX) { + mc_dev_err(-EINVAL, "buffer size %llu too big", memref->size); + return -EINVAL; + } + if (!mmu) /* cwsm_find automatically takes a reference */ cwsm = cwsm_find(client, memref); @@ -883,15 +895,22 @@ int client_gp_register_shared_mem(struct tee_client *client, int client_gp_release_shared_mem(struct tee_client *client, const struct gp_shared_memory *memref) { - struct cwsm *cwsm = cwsm_find(client, memref); + struct cwsm *cwsm; + int ret = 0; - if (!cwsm) - return -ENOENT; + mutex_lock(&client->cwsm_release_lock); + cwsm = cwsm_find(client, memref); + if (!cwsm) { + ret = -ENOENT; + goto end; + } /* Release reference taken by cwsm_find */ cwsm_put(cwsm); cwsm_put(cwsm); - return 0; +end: + mutex_unlock(&client->cwsm_release_lock); + return ret; } /* @@ -1117,8 +1136,15 @@ int client_cbuf_create(struct tee_client *client, u32 len, uintptr_t *addr, if (!client) return -EINVAL; - if (!len || len > BUFFER_LENGTH_MAX) + if (!len) { + mc_dev_err(-EINVAL, "buffer size 0 not supported"); return -EINVAL; + } + + if (len > BUFFER_LENGTH_MAX) { + mc_dev_err(-EINVAL, "buffer size %u too big", len); + return -EINVAL; + } order = get_order(len); if (order > MAX_ORDER) { @@ -1222,6 +1248,11 @@ static struct cbuf *cbuf_get_by_addr(struct tee_client *client, uintptr_t addr) /* * Remove a cbuf object from client, and mark it for freeing. * Freeing will happen once all current references are released. + * + * Note: this function could be subject to the same race condition as + * client_gp_release_shared_mem() and client_put_cwsm_sva(), but it is trusted + * as it can only be called by kernel drivers. So no lock around + * cbuf_get_by_addr() and the two tee_cbuf_put(). */ int client_cbuf_free(struct tee_client *client, uintptr_t addr) { @@ -1232,7 +1263,7 @@ int client_cbuf_free(struct tee_client *client, uintptr_t addr) return -EINVAL; } - /* Two references to put: the caller's and the one we just took */ + /* Release reference taken by cbuf_get_by_addr */ tee_cbuf_put(cbuf); mutex_lock(&client->cbufs_lock); cbuf->api_freed = true; diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.c index ef2645ac55f8..096dedf0a598 100644 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.c @@ -101,22 +101,6 @@ union fc_trace { } out; }; -union fc_switch_core { - union fc_common common; - - struct { - u32 cmd; - u32 core_id; - } in; - - struct { - u32 resp; - u32 ret; - u32 state; - u32 ext_info; - } out; -}; - union fc_nsiq { union fc_common common; @@ -151,6 +135,7 @@ union fc_yield { /* Structure to log SMC calls */ struct smc_log_entry { u64 cpu_clk; + int cpu_id; union fc_common fc; }; @@ -186,6 +171,7 @@ static inline int __smc(union fc_common *fc, const char *func) /* Log SMC call */ smc_log[smc_log_index].cpu_clk = local_clock(); + smc_log[smc_log_index].cpu_id = raw_smp_processor_id(); smc_log[smc_log_index].fc = *fc; if (++smc_log_index >= SMC_LOG_SIZE) smc_log_index = 0; @@ -275,7 +261,7 @@ int fc_init(uintptr_t addr, ptrdiff_t off, size_t q_len, size_t buf_len) fc.in.nq_info = (u32)(((addr_high & 0xFFFF) << 16) | (q_len & 0xFFFF)); /* mcp buffer start/length [16:16] [start, length] */ fc.in.mcp_info = (u32)((off << 16) | (buf_len & 0xFFFF)); - mc_dev_devel("cmd=%d, base=0x%08x,nq_info=0x%08x, mcp_info=0x%08x", + mc_dev_devel("cmd=0x%08x, base=0x%08x, nq_info=0x%08x, mcp_info=0x%08x", fc.in.cmd, fc.in.base, fc.in.nq_info, fc.in.mcp_info); return smc(&fc); @@ -351,21 +337,11 @@ int fc_yield(u32 timeslice) return smc(&fc); } -int fc_switch_core(int core_id) -{ - union fc_switch_core fc; - - memset(&fc, 0, sizeof(fc)); - fc.in.cmd = MC_FC_SWAP_CPU; - fc.in.core_id = core_id; - return smc(&fc); -} - static int show_smc_log_entry(struct kasnprintf_buf *buf, struct smc_log_entry *entry) { - return kasnprintf(buf, "%20llu %10d 0x%08x 0x%08x 0x%08x\n", - entry->cpu_clk, (s32)entry->fc.in.cmd, + return kasnprintf(buf, "%20llu %10d 0x%08x 0x%08x 0x%08x 0x%08x\n", + entry->cpu_clk, entry->cpu_id, entry->fc.in.cmd, entry->fc.in.param[0], entry->fc.in.param[1], entry->fc.in.param[2]); } @@ -378,7 +354,7 @@ int mc_fastcall_debug_smclog(struct kasnprintf_buf *buf) { int i, ret = 0; - ret = kasnprintf(buf, "%20s %10s %-10s %-10s %-10s\n", + ret = kasnprintf(buf, "%10s %20s %10s %-10s %-10s %-10s\n", "CPU id", "CPU clock", "command", "param1", "param2", "param3"); if (ret < 0) return ret; diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.h index c93e09a732e4..fdd554000022 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/fastcall.h @@ -21,7 +21,6 @@ int fc_trace_init(phys_addr_t buffer, u32 size); int fc_trace_deinit(void); int fc_nsiq(u32 session_id, u32 payload); int fc_yield(u32 timeslice); -int fc_switch_core(int core_id); int mc_fastcall_debug_smclog(struct kasnprintf_buf *buf); diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/iwp.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/iwp.c index 68c3417c7074..5a81f6b96b18 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/iwp.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/iwp.c @@ -414,9 +414,19 @@ static int iwp_operation_to_iws(struct gp_operation *operation, case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: if (operation->params[i].tmpref.buffer) { + struct gp_temp_memref *tmpref; + + tmpref = &operation->params[i].tmpref; /* Prepare buffer to map */ - bufs[i].va = operation->params[i].tmpref.buffer; - bufs[i].len = operation->params[i].tmpref.size; + bufs[i].va = tmpref->buffer; + if (tmpref->size > BUFFER_LENGTH_MAX) { + mc_dev_err(-EINVAL, + "buffer size %llu too big", + tmpref->size); + return -EINVAL; + } + + bufs[i].len = tmpref->size; if (param_type == TEEC_MEMREF_TEMP_INPUT) bufs[i].flags = MC_IO_MAP_INPUT; else if (param_type == TEEC_MEMREF_TEMP_OUTPUT) diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/logging.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/logging.c index 5e45c397a72c..ae3153f06024 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/logging.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/logging.c @@ -45,6 +45,10 @@ #define LOG_INTEGER_DECIMAL (0x0200) #define LOG_INTEGER_SIGNED (0x0400) +/* active cpu id */ +#define LOG_CPUID_MASK (0xF000) +#define LOG_CPUID_SHIFT 12 + struct mc_logmsg { u16 ctrl; /* Type and format of data */ u16 source; /* Unique value for each event source */ @@ -80,19 +84,18 @@ static struct logging_ctx { bool dead; } log_ctx; -static inline void log_eol(u16 source) +static inline void log_eol(u16 source, u32 cpuid) { if (!log_ctx.line_len) return; if (log_ctx.prev_source) /* TEE user-space */ - dev_info(g_ctx.mcd, "%03x|%s\n", log_ctx.prev_source, - log_ctx.line); + dev_info(g_ctx.mcd, "%03x(%u)|%s\n", log_ctx.prev_source, + cpuid, log_ctx.line); else /* TEE kernel */ - dev_info(g_ctx.mcd, "mtk|%s\n", log_ctx.line); - + dev_info(g_ctx.mcd, "mtk(%u)|%s\n", cpuid, log_ctx.line); log_ctx.line[0] = '\0'; log_ctx.line_len = 0; } @@ -101,34 +104,33 @@ static inline void log_eol(u16 source) * Collect chars in log_ctx.line buffer and output the buffer when it is full. * No locking needed because only "mobicore_log" thread updates this buffer. */ -static inline void log_char(char ch, u16 source) +static inline void log_char(char ch, u16 source, u32 cpuid) { if (ch == '\0') return; if (ch == '\n' || ch == '\r') { - log_eol(source); + log_eol(source, cpuid); return; } - if (log_ctx.line_len >= LOG_LINE_SIZE || - source != log_ctx.prev_source) - log_eol(source); + if (log_ctx.line_len >= LOG_LINE_SIZE || source != log_ctx.prev_source) + log_eol(source, cpuid); log_ctx.line[log_ctx.line_len++] = ch; log_ctx.line[log_ctx.line_len] = 0; log_ctx.prev_source = source; } -static inline void log_string(u32 ch, u16 source) +static inline void log_string(u32 ch, u16 source, u32 cpuid) { while (ch) { - log_char(ch & 0xFF, source); + log_char(ch & 0xFF, source, cpuid); ch >>= 8; } } -static inline void log_number(u32 format, u32 value, u16 source) +static inline void log_number(u32 format, u32 value, u16 source, u32 cpuid) { int width = (format & LOG_LENGTH_MASK) >> LOG_LENGTH_SHIFT; char fmt[16]; @@ -145,24 +147,25 @@ static inline void log_number(u32 format, u32 value, u16 source) snprintf(buffer, sizeof(buffer), fmt, value); while (*reader) - log_char(*reader++, source); + log_char(*reader++, source, cpuid); } static inline int log_msg(void *data) { struct mc_logmsg *msg = (struct mc_logmsg *)data; int log_type = msg->ctrl & LOG_TYPE_MASK; + int cpuid = ((msg->ctrl & LOG_CPUID_MASK) >> LOG_CPUID_SHIFT); switch (log_type) { case LOG_TYPE_CHAR: - log_string(msg->log_data, msg->source); + log_string(msg->log_data, msg->source, cpuid); break; case LOG_TYPE_INTEGER: - log_number(msg->ctrl, msg->log_data, msg->source); + log_number(msg->ctrl, msg->log_data, msg->source, cpuid); break; } if (msg->ctrl & LOG_EOL) - log_eol(msg->source); + log_eol(msg->source, cpuid); return sizeof(*msg); } @@ -207,7 +210,7 @@ void logging_run(void) /* * Setup MobiCore kernel log. It assumes it's running on CORE 0! - * The fastcall will complain is that is not the case! + * The fastcall will complain if that is not the case! */ int logging_init(phys_addr_t *buffer, u32 *size) { diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/main.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/main.c index cf28fcf6fac7..6bd5264c7ce3 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/main.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/main.c @@ -23,7 +23,6 @@ #include "public/mc_user.h" #include "public/mc_admin.h" /* MC_ADMIN_DEVNODE */ -#include "public/mc_linux_api.h" /* mc_switch_core */ #include "platform.h" /* MC_PM_RUNTIME */ #include "main.h" @@ -38,6 +37,7 @@ #include "xen_fe.h" #include "build_tag.h" +/* ExySp */ #define MC_DEVICE_PROPNAME "samsung,exynos-tee" /* Default entry for our driver in device tree */ @@ -238,43 +238,6 @@ static const struct file_operations debug_struct_counters_ops = { .llseek = default_llseek, }; -static ssize_t debug_coreswitch_write(struct file *file, - const char __user *buffer, - size_t buffer_len, loff_t *ppos) -{ - int new_cpu = 0; - - /* Invalid data, nothing to do */ - if (buffer_len < 1) - return -EINVAL; - - if (kstrtoint_from_user(buffer, buffer_len, 0, &new_cpu)) - return -EINVAL; - - mc_dev_devel("set active cpu to %d", new_cpu); - mc_switch_core(new_cpu); - return buffer_len; -} - -static ssize_t debug_coreswitch_read(struct file *file, char __user *buffer, - size_t buffer_len, loff_t *ppos) -{ - char cpu_str[8]; - int ret = 0; - - ret = snprintf(cpu_str, sizeof(cpu_str), "%d\n", mc_active_core()); - if (ret < 0) - return -EINVAL; - - return simple_read_from_buffer(buffer, buffer_len, ppos, - cpu_str, ret); -} - -static const struct file_operations debug_coreswitch_ops = { - .write = debug_coreswitch_write, - .read = debug_coreswitch_read, -}; - static inline int device_user_init(void) { struct device *dev; @@ -652,8 +615,6 @@ static int mobicore_probe(struct platform_device *pdev) /* Create debugfs info entries */ debugfs_create_file("structs_counters", 0400, g_ctx.debug_dir, NULL, &debug_struct_counters_ops); - debugfs_create_file("active_cpu", 0600, g_ctx.debug_dir, NULL, - &debug_coreswitch_ops); /* Initialize common API layer */ client_init(); @@ -686,19 +647,18 @@ static int mobicore_probe(struct platform_device *pdev) ret = device_admin_init(); if (ret) goto err_admin; - } #ifndef MC_DELAYED_TEE_START - ret = mobicore_start(); + ret = mobicore_start(); #endif - if (ret) - goto err_start; + if (ret) + goto err_start; + } return 0; err_start: - if (!is_xen_domu()) - device_admin_exit(); + device_admin_exit(); err_admin: device_common_exit(); err_common: diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcifc.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcifc.h index 312dfe088d1e..a1d46e84c205 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcifc.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcifc.h @@ -37,14 +37,12 @@ #define MC_FC_INIT MC_FC_STD32(1) /**< Initializing FastCall. */ #define MC_FC_INFO MC_FC_STD32(2) /**< Info FastCall. */ #define MC_FC_MEM_TRACE MC_FC_STD32(10) /**< Enable SWd tracing via memory */ -#define MC_FC_SWAP_CPU MC_FC_STD32(54) /**< Change new active Core */ #else #define MC_FC_INIT ((u32)(-1)) /**< Initializing FastCall. */ #define MC_FC_INFO ((u32)(-2)) /**< Info FastCall. */ #define MC_FC_MEM_TRACE ((u32)(-31)) /**< Enable SWd tracing via memory */ -#define MC_FC_SWAP_CPU ((u32)(0x84000005)) /**< Change new active Core */ #endif @@ -129,6 +127,10 @@ #define MC_EXT_INFO_ID_MC_EXC_UUID1 24 #define MC_EXT_INFO_ID_MC_EXC_UUID2 25 #define MC_EXT_INFO_ID_MC_EXC_UUID3 26 +/**< MobiCore exception handler last crashing task offset */ +#define MC_EXT_INFO_ID_TASK_OFFSET 27 +/**< MobiCore exception handler last crashing task's mclib offset */ +#define MC_EXT_INFO_ID_MCLIB_OFFSET 28 /** @} */ diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcimcp.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcimcp.h index 16a11071aa99..c75618db835b 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcimcp.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/mci/mcimcp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 TRUSTONIC LIMITED + * Copyright (c) 2013-2018 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -124,6 +124,8 @@ enum cmd_id { MC_MCP_CMD_LOAD_TOKEN = 0x0B, /** Check that TA can be loaded */ MC_MCP_CMD_CHECK_LOAD_TA = 0x0C, + /** Load a decryption key */ + MC_MCP_CMD_LOAD_SYSENC_KEY_SO = 0x0D, }; /* @@ -398,6 +400,25 @@ struct rsp_load_token { struct rsp_header rsp_header; /** Response header */ }; +/** @defgroup MCPLOADKEYSO + * Load a key SO from the normal world and share it with the TEE + * If something fails, the device attestation functionality will be disabled + */ + +/** Load key SO */ +struct cmd_load_key_so { + struct cmd_header cmd_header; /** Command header */ + u32 wsm_data_type; /** Type of MMU */ + u64 adr_load_data; /** Physical address of the MMU */ + u64 ofs_load_data; /** Offset to the data */ + u64 len_load_data; /** Length of the data */ +}; + +/** Load key SO Command Response */ +struct rsp_load_key_so { + struct rsp_header rsp_header; /** Response header */ +}; + /** Structure of the MCP buffer */ union mcp_message { struct init_values init_values; /** Initialisation values */ @@ -421,11 +442,10 @@ union mcp_message { struct rsp_load_token rsp_load_token; struct cmd_check_load cmd_check_load; /** TA load check */ struct rsp_check_load rsp_check_load; + struct cmd_load_key_so cmd_load_key_so;/** Load key SO */ + struct rsp_load_key_so rsp_load_key_so; }; -/** Minimum MCP buffer length (in bytes) */ -#define MIN_MCP_LEN sizeof(mcp_message_t) - #define MC_FLAG_NO_SLEEP_REQ 0 #define MC_FLAG_REQ_TO_SLEEP 1 @@ -441,7 +461,7 @@ struct sleep_mode { /** MobiCore status flags */ struct mcp_flags { - /** If not MC_FLAG_SCHEDULE_IDLE, MobiCore needsscheduling */ + /** If not MC_FLAG_SCHEDULE_IDLE, MobiCore needs scheduling */ u32 schedule; struct sleep_mode sleep_mode; /** Secure-world sleep timeout in milliseconds */ diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.c index f8a078f43f9d..30d9ffd217f3 100644 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.c @@ -115,6 +115,8 @@ static const char *cmd_to_string(enum cmd_id id) return "load token"; case MC_MCP_CMD_CHECK_LOAD_TA: return "check load TA"; + case MC_MCP_CMD_LOAD_SYSENC_KEY_SO: + return "load Key SO"; } return "unknown"; } @@ -528,6 +530,19 @@ int mcp_load_check(const struct tee_object *obj, return mcp_cmd(&cmd, 0, NULL, &cmd.cmd_check_load.uuid); } +int mcp_load_key_so(uintptr_t data, const struct mcp_buffer_map *map) +{ + union mcp_message cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd_header.cmd_id = MC_MCP_CMD_LOAD_SYSENC_KEY_SO; + cmd.cmd_load_key_so.wsm_data_type = map->type; + cmd.cmd_load_key_so.adr_load_data = map->addr; + cmd.cmd_load_key_so.ofs_load_data = map->offset; + cmd.cmd_load_key_so.len_load_data = map->length; + return mcp_cmd(&cmd, 0, NULL, NULL); +} + int mcp_open_session(struct mcp_session *session, struct mcp_open_info *info, bool *tci_in_use) { diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.h index 436e9f59c249..12345be89897 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/mcp.h @@ -93,6 +93,7 @@ int mcp_get_version(struct mc_version_info *version_info); int mcp_load_token(uintptr_t data, const struct mcp_buffer_map *buffer_map); int mcp_load_check(const struct tee_object *obj, const struct mcp_buffer_map *buffer_map); +int mcp_load_key_so(uintptr_t data, const struct mcp_buffer_map *buffer_map); int mcp_open_session(struct mcp_session *session, struct mcp_open_info *info, bool *tci_in_use); int mcp_close_session(struct mcp_session *session); diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/mmu.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/mmu.c index 20276eb9ff4d..f6c13f0ec045 100644 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/mmu.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/mmu.c @@ -124,6 +124,23 @@ static inline long gup_local(struct mm_struct *mm, uintptr_t start, } #endif +static inline long gup_local_repeat(struct mm_struct *mm, uintptr_t start, + unsigned long nr_pages, int write, + struct page **pages) +{ + int retries = 10; + long ret = 0; + + while (retries--) { + ret = gup_local(mm, start, nr_pages, write, pages); + + if (-EBUSY != ret) + break; + } + + return ret; +} + /* * A table that could be either a pmd or pte */ @@ -453,16 +470,17 @@ struct tee_mmu *tee_mmu_create(struct mm_struct *mm, * Linux creates (page faults) the underlying pages if * missing. */ - gup_ret = gup_local(mm, (uintptr_t)reader, - nr_pages, 1, pages); + gup_ret = gup_local_repeat(mm, (uintptr_t)reader, + nr_pages, 1, pages); if ((gup_ret == -EFAULT) && !writeable) { /* * If mapping read/write fails, and the buffer * is to be shared as input only, try to map * again read-only. */ - gup_ret = gup_local(mm, (uintptr_t)reader, - nr_pages, 0, pages); + gup_ret = gup_local_repeat(mm, + (uintptr_t)reader, + nr_pages, 0, pages); } up_read(&mm->mmap_sem); if (gup_ret < 0) { diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/nq.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/nq.c index 94a95c57ec54..45c51e333921 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/nq.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/nq.c @@ -12,7 +12,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -29,7 +28,6 @@ #include "platform.h" /* CPU-related information */ #include "public/mc_user.h" -#include "public/mc_linux_api.h" /* mc_switch_core */ #include "mci/mcifc.h" #include "mci/mciiwp.h" @@ -47,16 +45,6 @@ #define SCHEDULING_FREQ 5 /**< N-SIQ every n-th time */ #define DEFAULT_TIMEOUT_MS 20000 /* We do nothing on timeout anyway */ -/* If not forced by platform header, use defaults below */ - -#ifndef CPU_IDS -#define CPU_IDS { 0x0000, 0x0001, 0x0002, 0x0003, \ - 0x0100, 0x0101, 0x0102, 0x0103, \ - 0x0200, 0x0201, 0x0202, 0x0203 } -#endif - -static const u32 cpu_ids[] = CPU_IDS; - static struct { struct mutex buffer_mutex; /* Lock on SWd communication buffer */ struct mcp_buffer *mcp_buffer; @@ -91,8 +79,6 @@ static struct { struct mcp_time *time; /* Scheduler */ - int active_cpu; /* We always start on CPU #0 */ - int next_cpu; /* If core switch required */ struct task_struct *tee_scheduler_thread; bool tee_scheduler_run; bool tee_hung; @@ -118,68 +104,6 @@ static struct { bool log_buffer_busy; } l_ctx; -#ifdef MC_SMC_FASTCALL -static inline int nq_set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) -{ - return 0; -} -#else /* MC_SMC_FASTCALL */ -static inline int nq_set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) -{ - return set_cpus_allowed_ptr(p, &new_mask); -} -#endif /* ! MC_SMC_FASTCALL */ - -static inline int switch_to_online_core(int dying_cpu) -{ - int cpu; - - if (l_ctx.active_cpu != dying_cpu) { - mc_dev_devel("not active CPU, no action taken"); - return 0; - } - - /* Chose the first online CPU and switch! */ - for_each_online_cpu(cpu) { - if (cpu != dying_cpu) { - mc_dev_info("CPU #%d is dying, switching to CPU #%d", - dying_cpu, cpu); - return mc_switch_core(cpu); - } - - mc_dev_devel("skipping CPU #%d", dying_cpu); - } - - return 0; -} - -#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE -static int cpu_notifer_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - int cpu = (int)(uintptr_t)hcpu; - - switch (action) { - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - mc_dev_devel("CPU #%d is going to die", cpu); - switch_to_online_core(cpu); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block cpu_notifer = { - .notifier_call = cpu_notifer_callback, -}; -#else -static int nq_cpu_down_prep(unsigned int cpu) -{ - mc_dev_devel("CPU #%d is going to die", cpu); - return switch_to_online_core(cpu); -} -#endif - static inline bool is_iwp_id(u32 id) { return (id & SID_IWP_NOTIFICATION) != 0; @@ -514,6 +438,12 @@ static void nq_dump_status(void) { MC_EXT_INFO_ID_MC_EXC_IPCMSG, "mcExcep.cause"}, /**< MobiCore exception handler last IPC data */ {MC_EXT_INFO_ID_MC_EXC_IPCDATA, "mcExcep.meta"}, + /**< MobiCore last crashing task offset */ + {MC_EXT_INFO_ID_TASK_OFFSET, + "faultRec.offset.task"}, + /**< MobiCore last crashing task's mcLib offset */ + {MC_EXT_INFO_ID_MCLIB_OFFSET, + "faultRec.offset.mclib"}, }; char uuid_str[33]; @@ -538,9 +468,9 @@ static void nq_dump_status(void) if (fc_info(status_map[i].index, NULL, &info)) return; - mc_dev_info(" %-20s= 0x%08x", status_map[i].msg, info); + mc_dev_info(" %-22s= 0x%08x", status_map[i].msg, info); if (ret >= 0) - ret = kasnprintf(&l_ctx.dump, "%-20s= 0x%08x\n", + ret = kasnprintf(&l_ctx.dump, "%-22s= 0x%08x\n", status_map[i].msg, info); } @@ -558,9 +488,9 @@ static void nq_dump_status(void) } } - mc_dev_info(" %-20s= 0x%s", "mcExcep.uuid", uuid_str); + mc_dev_info(" %-22s= 0x%s", "mcExcep.uuid", uuid_str); if (ret >= 0) - ret = kasnprintf(&l_ctx.dump, "%-20s= 0x%s\n", "mcExcep.uuid", + ret = kasnprintf(&l_ctx.dump, "%-22s= 0x%s\n", "mcExcep.uuid", uuid_str); if (ret < 0) { @@ -846,36 +776,13 @@ static inline bool tee_sleep(s32 timeout_ms) return timeout_ms == 0; } -static inline int nq_switch_core(void) -{ - int cpu = l_ctx.next_cpu; - int core_id; - int ret; - - if (cpu < 0 || cpu >= nr_cpu_ids || !cpu_online(cpu)) - return -EINVAL; - - core_id = cpu_ids[cpu]; - ret = fc_switch_core(core_id); - logging_run(); - if (ret) { - mc_dev_err(ret, "failed to switch core from %d to %d", - l_ctx.active_cpu, cpu); - return ret; - } - - mc_dev_devel("switched core from %d to %d", l_ctx.active_cpu, cpu); - l_ctx.active_cpu = cpu; - return ret; -} - /* * This thread, and only this thread, schedules the SWd. Hence, reading the idle * status and its associated timeout is safe from race conditions. */ static int tee_scheduler(void *arg) { - int timeslice = 0; /* Actually scheduling period */ + bool swd_notify = false; int ret = 0; /* Enable TEE clock */ @@ -937,36 +844,25 @@ static int tee_scheduler(void *arg) case NONE: break; case YIELD: - /* Yield forced: increment timeslice */ - timeslice++; + swd_notify = false; break; case NSIQ: - timeslice = 0; + swd_notify = true; break; case SUSPEND: /* Force N_SIQ */ - timeslice = 0; + swd_notify = true; set_sleep_mode_rq(MC_FLAG_REQ_TO_SLEEP); pm_request = true; break; case RESUME: /* Force N_SIQ */ - timeslice = 0; + swd_notify = true; set_sleep_mode_rq(MC_FLAG_NO_SLEEP_REQ); pm_request = true; break; } - /* Switch core */ - if (l_ctx.next_cpu != l_ctx.active_cpu && !nq_switch_core()) { - cpumask_t cpu_mask; - - cpumask_clear(&cpu_mask); - cpumask_set_cpu(l_ctx.active_cpu, &cpu_mask); - nq_set_cpus_allowed(l_ctx.tee_scheduler_thread, - cpu_mask); - } - l_ctx.request = NONE; nq_update_time(); mutex_unlock(&l_ctx.request_mutex); @@ -976,18 +872,18 @@ static int tee_scheduler(void *arg) l_ctx.mcp_buffer->flags.timeout_ms = -1; mutex_unlock(&l_ctx.buffer_mutex); - if (timeslice--) { - /* Resume SWd from where it was */ - fc_yield(timeslice); - } else { + if (swd_notify) { u32 session_id = 0; u32 payload = 0; retrieve_last_session_payload(&session_id, &payload); - timeslice = SCHEDULING_FREQ; + swd_notify = false; /* Call SWd scheduler */ fc_nsiq(session_id, payload); + } else { + /* Resume SWd from where it was */ + fc_yield(0); } /* Always flush log buffer after the SWd has run */ @@ -1097,8 +993,6 @@ int nq_start(void) return ret; } - /* The scheduler/fastcall thread MUST run on CPU 0 at startup */ - nq_set_cpus_allowed(l_ctx.tee_scheduler_thread, CPU_MASK_CPU0); wake_up_process(l_ctx.tee_scheduler_thread); wait_for_completion(&l_ctx.boot_complete); @@ -1129,21 +1023,6 @@ int nq_init(void) unsigned long mci; int ret; - if (nr_cpu_ids) { -#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE - ret = register_cpu_notifier(&cpu_notifer); -#else - ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, - "tee/trustonic:online", - NULL, nq_cpu_down_prep); -#endif - /* ExySp : Kinibi 410 */ - if (ret < 0) { - mc_dev_err(ret, "cpu online callback setup failed"); - goto err_register; - } - } - ret = mc_clock_init(); if (ret) goto err_clock; @@ -1214,13 +1093,6 @@ err_mci: err_logging: mc_clock_exit(); err_clock: - if (nr_cpu_ids) -#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE - unregister_cpu_notifier(&cpu_notifer); -#else - cpuhp_remove_state_nocalls(CPUHP_AP_ONLINE_DYN); -#endif -err_register: return ret; } @@ -1231,31 +1103,5 @@ void nq_exit(void) free_pages((unsigned long)l_ctx.mci, l_ctx.order); logging_exit(l_ctx.log_buffer_busy); - if (nr_cpu_ids) -#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE - unregister_cpu_notifier(&cpu_notifer); -#else - cpuhp_remove_state_nocalls(CPUHP_AP_ONLINE_DYN); -#endif mc_clock_exit(); } - -int mc_active_core(void) -{ - return l_ctx.active_cpu; -} - -int mc_switch_core(int cpu) -{ - if (cpu >= nr_cpu_ids) - return -EINVAL; - - if (!cpu_online(cpu)) - return -EPERM; - - l_ctx.next_cpu = cpu; - /* Ping the tee_scheduler thread to update */ - nq_scheduler_command(YIELD); - - return 0; -} diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/platform.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/platform.h index 761325cb91b7..52bfd1bddb7c 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/platform.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 TRUSTONIC LIMITED + * Copyright (c) 2013-2018 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -32,6 +32,8 @@ defined(CONFIG_SOC_EXYNOS5433) || defined(CONFIG_SOC_EXYNOS7870) || \ defined(CONFIG_SOC_EXYNOS8890) || defined(CONFIG_SOC_EXYNOS7880) || defined(CONFIG_SOC_EXYNOS8895) #define MC_INTR_SSIQ 255 +#elif defined(CONFIG_SOC_EXYNOS7885) +#define MC_INTR_SSIQ 97 #elif defined(CONFIG_SOC_EXYNOS7420) || defined(CONFIG_SOC_EXYNOS7580) #define MC_INTR_SSIQ 246 #endif diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_admin.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_admin.h index 1e4d4dbd13fc..1a1892953840 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_admin.h +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_admin.h @@ -76,6 +76,8 @@ struct mc_admin_load_info { _IOW(MC_IOC_MAGIC, 3, struct mc_admin_load_info) #define MC_ADMIN_IO_LOAD_CHECK \ _IOW(MC_IOC_MAGIC, 4, struct mc_admin_load_info) +#define MC_ADMIN_IO_LOAD_KEY_SO \ + _IOW(MC_IOC_MAGIC, 5, struct mc_admin_load_info) #ifdef __cplusplus } diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_linux_api.h b/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_linux_api.h deleted file mode 100755 index 65156e46d8ad..000000000000 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/public/mc_linux_api.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013-2017 TRUSTONIC LIMITED - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef _MC_LINUX_API_H_ -#define _MC_LINUX_API_H_ - -#include - -/* - * Switch TEE active core to core_num, defined as linux - * core id - */ -int mc_switch_core(int core_num); - -/* - * Return TEE active core as Linux core id - */ -int mc_active_core(void); - -#endif /* _MC_LINUX_API_H_ */ diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/session.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/session.c index 7ecfc5dadcd7..2facf8bc5398 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/session.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/session.c @@ -85,6 +85,11 @@ static int wsm_create(struct tee_session *session, struct tee_wsm *wsm, return -EINVAL; } + if (buf->len > BUFFER_LENGTH_MAX) { + mc_dev_err(-EINVAL, "buffer size %u too big", buf->len); + return -EINVAL; + } + wsm->mmu = client_mmu_create(session->client, buf, &wsm->cbuf); if (IS_ERR(wsm->mmu)) return PTR_ERR(wsm->mmu); @@ -326,8 +331,10 @@ static int check_prepare_identity(const struct mc_identity *identity, struct mc_identity *mcp_id = (struct mc_identity *)mcp_identity; u8 hash[SHA1_HASH_SIZE] = { 0 }; bool application = false; + bool supplied_ca_identity = false; const void *data; unsigned int data_len; + static const u8 zero_buffer[sizeof(identity->login_data)] = { 0 }; /* Copy login type */ mcp_identity->login_type = identity->login_type; @@ -365,16 +372,21 @@ static int check_prepare_identity(const struct mc_identity *identity, switch (identity->login_type) { case LOGIN_PUBLIC: - case LOGIN_USER: case LOGIN_GROUP: break; + case LOGIN_USER: + data = NULL; + data_len = 0; + break; case LOGIN_APPLICATION: application = true; + supplied_ca_identity = true; data = NULL; data_len = 0; break; case LOGIN_USER_APPLICATION: application = true; + supplied_ca_identity = true; data = &mcp_id->uid; data_len = sizeof(mcp_id->uid); break; @@ -390,7 +402,17 @@ static int check_prepare_identity(const struct mc_identity *identity, return -EINVAL; } - if (application) { + /* let the supplied login_data pass through if it is LOGIN_APPLICATION + * or LOGIN_USER_APPLICATION and not a zero-filled buffer + * That buffer is expected to contain a NWd computed hash containing the + * CA identity + */ + if (supplied_ca_identity && + memcmp(identity->login_data, zero_buffer, + sizeof(identity->login_data)) != 0) { + memcpy(&mcp_id->login_data, identity->login_data, + sizeof(mcp_id->login_data)); + } else if (application) { int ret = hash_path_and_data(task, hash, data, data_len); if (ret) { diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/teeclientapi.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/teeclientapi.c index 071737d6f79e..3100ed46b5dc 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/teeclientapi.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/teeclientapi.c @@ -247,7 +247,7 @@ u32 teec_open_session(struct teec_context *context, u32 *return_origin) { struct mc_uuid_t uuid; - struct mc_identity identity; + struct mc_identity identity = {0}; struct tee_client *client = NULL; struct gp_operation gp_op; struct gp_return gp_ret; diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/user.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/user.c index e2b63f300a36..b34ae3c6f309 100755 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/user.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/user.c @@ -384,8 +384,11 @@ static int user_mmap(struct file *file, struct vm_area_struct *vmarea) { struct tee_client *client = get_client(file); - if ((vmarea->vm_end - vmarea->vm_start) > BUFFER_LENGTH_MAX) + if ((vmarea->vm_end - vmarea->vm_start) > BUFFER_LENGTH_MAX) { + mc_dev_err(-EINVAL, "buffer size %lu too big", + vmarea->vm_end - vmarea->vm_start); return -EINVAL; + } /* Alloc contiguous buffer for this client */ return client_cbuf_create(client, diff --git a/drivers/gud/gud-exynos9610/MobiCoreDriver/xen_fe.c b/drivers/gud/gud-exynos9610/MobiCoreDriver/xen_fe.c index ac2aa480c44a..7dbfb9536078 100644 --- a/drivers/gud/gud-exynos9610/MobiCoreDriver/xen_fe.c +++ b/drivers/gud/gud-exynos9610/MobiCoreDriver/xen_fe.c @@ -39,6 +39,10 @@ static struct { /* GP operations */ struct mutex gp_operations_lock; struct list_head gp_operations; + /* Last back-end state, + * to overcome an issue in some Xen implementations + */ + int last_be_state; } l_ctx; struct xen_fe_mc_session { @@ -1131,6 +1135,13 @@ static void xen_fe_backend_changed(struct xenbus_device *xdev, struct tee_xfe *xfe = l_ctx.xfe; mc_dev_devel("be state changed to %d", be_state); + + if (be_state == l_ctx.last_be_state) { + /* Protection against duplicated notifications (TBUG-1387) */ + mc_dev_devel("be state (%d) already set... ignoring", be_state); + return; + } + switch (be_state) { case XenbusStateUnknown: case XenbusStateInitialising: @@ -1149,6 +1160,9 @@ static void xen_fe_backend_changed(struct xenbus_device *xdev, case XenbusStateReconfigured: break; } + + /* Refresh last back-end state */ + l_ctx.last_be_state = be_state; } static struct xenbus_driver xen_fe_driver = { diff --git a/drivers/gud/gud-exynos9610/TlcTui/build_tag.h b/drivers/gud/gud-exynos9610/TlcTui/build_tag.h index d457b3511533..eefa20629307 100644 --- a/drivers/gud/gud-exynos9610/TlcTui/build_tag.h +++ b/drivers/gud/gud-exynos9610/TlcTui/build_tag.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 TRUSTONIC LIMITED + * Copyright (c) 2013-2018 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -13,5 +13,5 @@ */ #ifndef MOBICORE_COMPONENT_BUILD_TAG #define MOBICORE_COMPONENT_BUILD_TAG \ - "t-base-Exynos-Android-410a-v001-20180329_190510_46723_76543" + "t-base-Exynos-Android-410a-V003-20180920_200500_55985_85552" #endif diff --git a/drivers/gud/gud-exynos9610/TlcTui/main.c b/drivers/gud/gud-exynos9610/TlcTui/main.c index f4c8cc7d8954..2e39643a5bb0 100755 --- a/drivers/gud/gud-exynos9610/TlcTui/main.c +++ b/drivers/gud/gud-exynos9610/TlcTui/main.c @@ -50,6 +50,15 @@ static long tui_ioctl(struct file *f, unsigned int cmd, unsigned long arg) pr_info("t-base-tui module: ioctl 0x%x ", cmd); switch (cmd) { + case TUI_IO_SET_RESOLUTION: + /* TLC_TUI_CMD_SET_RESOLUTION is for specific platforms + * that rely on onConfigurationChanged to set resolution + * it has no effect on Trustonic reference implementaton. + */ + pr_info("TLC_TUI_CMD_SET_RESOLUTION\n"); + /* NOT IMPLEMENTED */ + ret = 0; + break; case TUI_IO_NOTIFY: pr_info("TUI_IO_NOTIFY\n"); diff --git a/drivers/gud/gud-exynos9610/TlcTui/public/tui_ioctl.h b/drivers/gud/gud-exynos9610/TlcTui/public/tui_ioctl.h index 86f123c5e478..65f85310c720 100755 --- a/drivers/gud/gud-exynos9610/TlcTui/public/tui_ioctl.h +++ b/drivers/gud/gud-exynos9610/TlcTui/public/tui_ioctl.h @@ -35,6 +35,12 @@ struct tlc_tui_response_t { u32 screen_metrics[3]; }; +/* Resolution */ +struct tlc_tui_resolution_t { + u32 width; + u32 height; +}; + /* Command IDs */ /* */ #define TLC_TUI_CMD_NONE 0 @@ -64,6 +70,12 @@ struct tlc_tui_response_t { #define TLC_TUI_CMD_HIDE_SURFACE 7 #define TLC_TUI_CMD_GET_RESOLUTION 8 +/* TLC_TUI_CMD_SET_RESOLUTION is for specific platforms + * that rely on onConfigurationChanged to set resolution + * it has no effect on Trustonic reference implementaton. + */ +#define TLC_TUI_CMD_SET_RESOLUTION 9 + /* Return codes */ #define TLC_TUI_OK 0 #define TLC_TUI_ERROR 1 @@ -80,6 +92,7 @@ struct tlc_tui_response_t { #define TUI_IO_WAITCMD _IOR(TUI_IO_MAGIC, 2, struct tlc_tui_command_t) #define TUI_IO_ACK _IOW(TUI_IO_MAGIC, 3, struct tlc_tui_response_t) #define TUI_IO_INIT_DRIVER _IO(TUI_IO_MAGIC, 4) +#define TUI_IO_SET_RESOLUTION _IOW(TUI_IO_MAGIC, 9, struct tlc_tui_resolution_t) #ifdef INIT_COMPLETION #define reinit_completion(x) INIT_COMPLETION(*(x)) diff --git a/drivers/gud/gud-exynos9610/TlcTui/tlcTui.c b/drivers/gud/gud-exynos9610/TlcTui/tlcTui.c index f9e133fca366..e2f61e16390c 100755 --- a/drivers/gud/gud-exynos9610/TlcTui/tlcTui.c +++ b/drivers/gud/gud-exynos9610/TlcTui/tlcTui.c @@ -253,8 +253,11 @@ static void tlc_process_cmd(void) TLC_TUI_CMD_START_ACTIVITY, dci->cmd_nwd.payload.alloc_data.num_of_buff, dci->cmd_nwd.payload.alloc_data.alloc_size); - if (ret != TUI_DCI_OK) + if (ret != TUI_DCI_OK) { + pr_debug("%s:%d return value is 0x%x.\n", __func__, + __LINE__, ret); break; + } /*****************************************************************************/ -- 2.20.1