summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungho Lee <sh1006.lee@samsung.com>2016-07-04 16:22:05 +0900
committerjino.cho <jino.cho@samsung.com>2017-03-03 17:02:45 +0900
commitd3ef33a80d7655791726b9fb8e8acb92ed6204b7 (patch)
treed7ac05a2543220e8f44c8d55e85da983e1932e8a
parentfff132a2bce94614020152701acfd32c3ed5b4da (diff)
downloadlinux-3.10-artik-d3ef33a80d7655791726b9fb8e8acb92ed6204b7.tar.gz
linux-3.10-artik-d3ef33a80d7655791726b9fb8e8acb92ed6204b7.tar.bz2
linux-3.10-artik-d3ef33a80d7655791726b9fb8e8acb92ed6204b7.zip
misc: artiktee: Support 64bit kernel with compat_ and Add tzinfo for debugging
This patch to support 32bit user mode on 64bit kernel, so compat_ioctl is added to file operations. tzinfo file is to fetch TEE information for debugging. tzinfo can be enabled when Secure OS is built in debug mode. Change-Id: Ida28ce1c241f90997f5c056c877b8c801d31a5d2 Signed-off-by: Seungho Lee <sh1006.lee@samsung.com>
-rw-r--r--drivers/misc/artiktee/Kconfig8
-rw-r--r--drivers/misc/artiktee/Makefile10
-rw-r--r--drivers/misc/artiktee/circular_buffer.h2
-rw-r--r--drivers/misc/artiktee/log_level_ree.h92
-rw-r--r--drivers/misc/artiktee/log_system_api_ext.h152
-rw-r--r--drivers/misc/artiktee/smc_interface.h4
-rw-r--r--[-rwxr-xr-x]drivers/misc/artiktee/ss_core.c1
-rw-r--r--drivers/misc/artiktee/ss_dev.c5
-rw-r--r--[-rwxr-xr-x]drivers/misc/artiktee/ss_file.c2
-rw-r--r--drivers/misc/artiktee/ss_rpmb.c2
-rw-r--r--drivers/misc/artiktee/sstransaction.c3
-rw-r--r--[-rwxr-xr-x]drivers/misc/artiktee/tzdev.h61
-rw-r--r--drivers/misc/artiktee/tzdev_init.h1
-rw-r--r--drivers/misc/artiktee/tzdev_internal.h30
-rw-r--r--drivers/misc/artiktee/tzdev_main.c67
-rw-r--r--drivers/misc/artiktee/tzdev_plat.c6
-rw-r--r--drivers/misc/artiktee/tzdev_smc.c22
-rw-r--r--drivers/misc/artiktee/tzdev_smc.h4
-rw-r--r--drivers/misc/artiktee/tzinfo.c94
-rw-r--r--drivers/misc/artiktee/tzinfo.h25
-rw-r--r--drivers/misc/artiktee/tzlinkmgr.c1
-rw-r--r--drivers/misc/artiktee/tzlog_core.c300
-rw-r--r--drivers/misc/artiktee/tzlog_core.h45
-rw-r--r--drivers/misc/artiktee/tzlog_print.c224
-rw-r--r--drivers/misc/artiktee/tzlog_print.h32
-rw-r--r--drivers/misc/artiktee/tzlog_process.c490
-rw-r--r--drivers/misc/artiktee/tzlog_process.h29
-rw-r--r--drivers/misc/artiktee/tzmem.c79
-rw-r--r--drivers/misc/artiktee/tzsys.c83
-rw-r--r--drivers/misc/artiktee/tzwsm.c2
30 files changed, 1754 insertions, 122 deletions
diff --git a/drivers/misc/artiktee/Kconfig b/drivers/misc/artiktee/Kconfig
index 156767da8c8..484c8c4ef5f 100644
--- a/drivers/misc/artiktee/Kconfig
+++ b/drivers/misc/artiktee/Kconfig
@@ -10,4 +10,12 @@ config ARTIK_TRUSTZONE_DRIVER
help
This driver allows you can communicate with ARTIK Secure OS.
When you use this driver, the platform has to support Secure OS.
+
+config ARTIK_FETCH_TEE_INFO
+ bool "ARTIK Fetch TEE information"
+ depends on (ARTIK_TRUSTZONE_DRIVER)
+ default n
+ help
+ This driver supports to fetch information in TEE side for ARTIK.
+ If Secure OS is built in Debug mode, you can use this feature.
endmenu
diff --git a/drivers/misc/artiktee/Makefile b/drivers/misc/artiktee/Makefile
index bed729e5648..f0c743c56b2 100644
--- a/drivers/misc/artiktee/Makefile
+++ b/drivers/misc/artiktee/Makefile
@@ -1,10 +1,15 @@
MODULE_NAME := tzdev
ccflags-y := -DCONFIG_SECOS_NO_RPMB=1 -DCONFIG_PSCI=1
+ifeq ($(CONFIG_ARTIK_FETCH_TEE_INFO),y)
+ccflags-y += -DCONFIG_FETCH_TEE_INFO=1
+endif
obj-$(CONFIG_ARTIK_TRUSTZONE_DRIVER) += $(MODULE_NAME).o
$(MODULE_NAME)-objs += tzdev_main.o
-$(MODULE_NAME)-objs += tzlog.o
+$(MODULE_NAME)-objs += tzlog_print.o
+$(MODULE_NAME)-objs += tzlog_core.o
+$(MODULE_NAME)-objs += tzlog_process.o
$(MODULE_NAME)-objs += sstransaction.o
$(MODULE_NAME)-objs += tzpage.o
$(MODULE_NAME)-objs += ss_core.o
@@ -17,3 +22,6 @@ $(MODULE_NAME)-objs += tzlinkmgr.o
$(MODULE_NAME)-objs += tzwsm.o
$(MODULE_NAME)-objs += tzmem.o
$(MODULE_NAME)-objs += tzdev_plat.o
+ifeq ($(CONFIG_ARTIK_FETCH_TEE_INFO),y)
+$(MODULE_NAME)-objs += tzinfo.o
+endif
diff --git a/drivers/misc/artiktee/circular_buffer.h b/drivers/misc/artiktee/circular_buffer.h
index cf66c442893..c8bfc4d7894 100644
--- a/drivers/misc/artiktee/circular_buffer.h
+++ b/drivers/misc/artiktee/circular_buffer.h
@@ -34,7 +34,7 @@
#include <linux/uaccess.h>
#include <linux/uio.h>
#include <linux/slab.h>
-#include "tzdev_internal.h"
+#include "tzlog_print.h"
#endif
#else
#include <sys/types.h>
diff --git a/drivers/misc/artiktee/log_level_ree.h b/drivers/misc/artiktee/log_level_ree.h
new file mode 100644
index 00000000000..1fb95f9aea6
--- /dev/null
+++ b/drivers/misc/artiktee/log_level_ree.h
@@ -0,0 +1,92 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Author: Jungkyuen <jklolo.lee@samsung.com>
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#ifndef __LOG_LEVEL_H__
+#define __LOG_LEVEL_H__
+
+typedef enum {
+#ifndef LOG_DEBUG
+ LOG_EMERG = 0,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG,
+#endif
+ LOG_SILENT = 8,
+} usr_log_level;
+
+typedef enum {
+ K_EMERG = 0,
+ K_ALERT,
+ K_CRIT,
+ K_ERR,
+ K_WARNING,
+ K_NOTICE,
+ K_INFO,
+ K_DEBUG,
+ K_SILENT,
+} kernel_log_level;
+
+typedef enum {
+ SWD_USERMODE = 1,
+ SWD_KERNMODE,
+ NWD_USERMODE,
+ NWD_KERNMODE,
+ SWD_ENC_USERMODE,
+ SWD_ENC_KERNMODE,
+} log_header_info;
+
+/* Ree World */
+#ifndef NDEBUG
+#define TZDAEMON_DLOG_KERN_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDAEMON_DLOG_TA_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDAEMON_FILE_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDAEMON_SYSLOG_LOG_LEVEL LOG_DEBUG /* Output Default */
+#define TZDEV_TEE_LOG_LEVEL K_INFO /* OutPut Default */
+
+#define TZDAEMON_LOCAL_DLOG_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDAEMON_LOCAL_FILE_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDAEMON_LOCAL_SYSLOG_LOG_LEVEL LOG_DEBUG /* OutPut Default */
+#define TZDEV_LOCAL_LOG_LEVEL K_INFO /* OutPut Default */
+
+#define NO_HEADER_LOG_LEVEL LOG_INFO /* Generation Default */
+#else
+#define TZDAEMON_DLOG_KERN_LOG_LEVEL LOG_ERR /* OutPut Default */
+#define TZDAEMON_DLOG_TA_LOG_LEVEL LOG_ERR /* OutPut Default */
+#define TZDAEMON_FILE_LOG_LEVEL LOG_ERR /* OutPut Default */
+#define TZDAEMON_SYSLOG_LOG_LEVEL LOG_SILENT /* Output Default */
+#define TZDEV_TEE_LOG_LEVEL K_ERR /* OutPut Default */
+
+#define TZDAEMON_LOCAL_DLOG_LOG_LEVEL LOG_ALERT /* OutPut Default */
+#define TZDAEMON_LOCAL_FILE_LOG_LEVEL LOG_ALERT /* OutPut Default */
+#define TZDAEMON_LOCAL_SYSLOG_LOG_LEVEL LOG_ALERT /* OutPut Default */
+#define TZDEV_LOCAL_LOG_LEVEL K_ALERT /* OutPut Default */
+
+#define NO_HEADER_LOG_LEVEL LOG_INFO /* Generation Default */
+#endif
+
+/* For Old Log Level */
+#define TZLOG_DEBUG K_DEBUG
+#define TZLOG_INFO K_INFO
+#define TZLOG_WARNING K_WARNING
+#define TZLOG_ERROR K_ERR
+
+#endif
diff --git a/drivers/misc/artiktee/log_system_api_ext.h b/drivers/misc/artiktee/log_system_api_ext.h
new file mode 100644
index 00000000000..0e2c67fa07e
--- /dev/null
+++ b/drivers/misc/artiktee/log_system_api_ext.h
@@ -0,0 +1,152 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Author: Soonhong Kwon <aron.kwon@samsung.com>
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#ifndef __LOG_SYSTEM_API_REE_H__
+#define __LOG_SYSTEM_API_REE_H__
+
+/* Changable */
+#define LOG_HD_MAGIC_SIZE 4
+#define LOG_HD_GP_SIZE 1
+#define LOG_HD_LEVEL_SIZE 1
+#define LOG_HD_LABEL_SIZE 2
+#define LOG_HD_BODY_SIZE 3
+#define LOG_HD_PID_SIZE 4
+
+/* Do Not Change */
+#define LOG_HD_MAGIC_POS 0
+#define LOG_HD_GP_POS ((LOG_HD_MAGIC_POS) + (LOG_HD_MAGIC_SIZE))
+#define LOG_HD_LEVEL_POS ((LOG_HD_GP_POS) + (LOG_HD_GP_SIZE))
+#define LOG_HD_LABEL_POS ((LOG_HD_LEVEL_POS) + (LOG_HD_LEVEL_SIZE))
+#define LOG_HD_BODY_POS ((LOG_HD_LABEL_POS) + (LOG_HD_LABEL_SIZE))
+#define LOG_HD_PID_POS ((LOG_HD_BODY_POS) + (LOG_HD_BODY_SIZE))
+#define LHDSIZE ((LOG_HD_PID_POS) + (LOG_HD_PID_SIZE))
+#define LOG_HD_MAGIC_VAL 0xAE18
+#define LOG_MAGIC "AE18"
+
+typedef struct {
+ uint32_t magic;
+ uint32_t log_gen_point;
+ uint32_t log_level;
+ uint32_t log_label_size;
+ uint32_t log_body_size;
+ uint32_t log_pid;
+} log_header_type;
+
+enum {
+ NO_MAGIC = 0,
+ TRUNCATED_MAGIC,
+ COMPLETE_MAGIC,
+};
+
+#define MIN(a, b) ((a > b) ? b : a)
+
+static inline uint32_t hex2int(char ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return (uint32_t) (ch - '0');
+ else if (ch >= 'a' && ch <= 'f')
+ return (uint32_t) (ch - 'a' + 10);
+ else if (ch >= 'A' && ch <= 'F')
+ return (uint32_t) (ch - 'A' + 10);
+ else
+ return 0;
+}
+
+static inline uint32_t get_log_gp(char *buffer)
+{ /* 1 Byte */
+ if (buffer == NULL)
+ return 0;
+
+ return hex2int(buffer[0]);
+}
+
+static inline uint32_t get_log_level(char *buffer)
+{ /* 1 Byte */
+ if (buffer == NULL)
+ return 0;
+
+ return hex2int(buffer[0]);
+}
+
+static inline uint32_t get_log_label_size(char *buffer)
+{ /* 2 Byte */
+ if (buffer == NULL)
+ return 0;
+
+ return (hex2int(buffer[0]) << 4) + (hex2int(buffer[1]));
+}
+
+static inline uint32_t get_log_body_size(char *buffer)
+{ /* 3 Byte */
+ if (buffer == NULL)
+ return 0;
+
+ return (hex2int(buffer[0]) << 8) +
+ (hex2int(buffer[1]) << 4) + (hex2int(buffer[2]));
+}
+
+static inline uint32_t get_log_pid(char *buffer)
+{
+ if (buffer == NULL)
+ return 0;
+
+ return (hex2int(buffer[0]) << 12) +
+ (hex2int(buffer[1]) << 8) +
+ (hex2int(buffer[2]) << 4) + (hex2int(buffer[3]));
+}
+
+static inline uint32_t get_log_header(char *buffer, log_header_type *header)
+{
+ int i = 0;
+ char temp[5] = LOG_MAGIC;
+
+ if (buffer == NULL || header == NULL)
+ return 0;
+
+ for (i = 0; i < 4; ++i) {
+ if (temp[i] != buffer[i])
+ return 0;
+ }
+ header->log_gen_point = get_log_gp(buffer + LOG_HD_GP_POS);
+ header->log_level = get_log_level(buffer + LOG_HD_LEVEL_POS);
+ header->log_label_size = get_log_label_size(buffer + LOG_HD_LABEL_POS);
+ header->log_body_size = get_log_body_size(buffer + LOG_HD_BODY_POS);
+ header->log_pid = get_log_pid(buffer + LOG_HD_PID_POS);
+ return 1;
+}
+
+static inline uint32_t get_check_magic(char *buffer)
+{
+ int i = 0;
+ char temp[5] = LOG_MAGIC;
+
+ uint32_t ret = NO_MAGIC;
+ if (buffer == NULL)
+ return 0;
+
+ for (i = 0; i < 4; ++i) {
+ if (temp[i] != buffer[i]) {
+ if (buffer[i] == 0)
+ ret = TRUNCATED_MAGIC;
+ break;
+ } else
+ ret = COMPLETE_MAGIC;
+ }
+ return ret;
+}
+#endif
diff --git a/drivers/misc/artiktee/smc_interface.h b/drivers/misc/artiktee/smc_interface.h
index f63bbbc6465..57ac9c75229 100644
--- a/drivers/misc/artiktee/smc_interface.h
+++ b/drivers/misc/artiktee/smc_interface.h
@@ -46,6 +46,10 @@
#define SMC_STD_REGISTER_PHYS_WSM 14
+#ifdef CONFIG_FETCH_TEE_INFO
+#define SMC_STD_FETCH_TEE_INFO 16
+#endif /* !CONFIG_FETCH_TEE_INFO */
+
/* TODO: this should be sent to PSCI */
#define SMC_PM_CPU_OFF 0
#define SMC_PM_SYSTEM_OFF 1
diff --git a/drivers/misc/artiktee/ss_core.c b/drivers/misc/artiktee/ss_core.c
index e7794375f31..1e1ccf759d0 100755..100644
--- a/drivers/misc/artiktee/ss_core.c
+++ b/drivers/misc/artiktee/ss_core.c
@@ -40,6 +40,7 @@
#include "tzdev_smc.h"
#include "sstransaction.h"
+#include "tzlog_print.h"
#ifndef CONFIG_SECOS_NO_SECURE_STORAGE
diff --git a/drivers/misc/artiktee/ss_dev.c b/drivers/misc/artiktee/ss_dev.c
index a12b18fea3d..d111ffd7527 100644
--- a/drivers/misc/artiktee/ss_dev.c
+++ b/drivers/misc/artiktee/ss_dev.c
@@ -36,7 +36,7 @@
#include "ss_rpmb.h"
#include "ss_core.h"
#include "ss_dev.h"
-#include "tzdev_internal.h"
+#include "tzlog_print.h"
#ifndef CONFIG_SECOS_NO_SECURE_STORAGE
@@ -96,6 +96,9 @@ static const struct file_operations storage_fops = {
.release = storage_release,
.mmap = storage_mmap,
.unlocked_ioctl = storage_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = storage_ioctl,
+#endif
};
static struct miscdevice storage = {
diff --git a/drivers/misc/artiktee/ss_file.c b/drivers/misc/artiktee/ss_file.c
index 00d5134f3cc..4f1ecfad079 100755..100644
--- a/drivers/misc/artiktee/ss_file.c
+++ b/drivers/misc/artiktee/ss_file.c
@@ -25,7 +25,7 @@
#include <linux/fs.h>
#include "ss_file.h"
-#include "tzdev_internal.h"
+#include "tzlog_print.h"
#ifndef CONFIG_SECOS_NO_SECURE_STORAGE
diff --git a/drivers/misc/artiktee/ss_rpmb.c b/drivers/misc/artiktee/ss_rpmb.c
index 2928818b3bc..ce607bb8b43 100644
--- a/drivers/misc/artiktee/ss_rpmb.c
+++ b/drivers/misc/artiktee/ss_rpmb.c
@@ -32,7 +32,7 @@
#if defined(CONFIG_MMC) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
#include "ss_rpmb.h"
-#include "tzdev_internal.h"
+#include "tzlog_print.h"
#define RPMB_DEVICE "mmcblk0rpmb"
diff --git a/drivers/misc/artiktee/sstransaction.c b/drivers/misc/artiktee/sstransaction.c
index d6c3fd8f2f0..31e3e2b0364 100644
--- a/drivers/misc/artiktee/sstransaction.c
+++ b/drivers/misc/artiktee/sstransaction.c
@@ -31,6 +31,9 @@
#include "sstransaction.h"
#include "tzdev.h"
#include "tzdev_internal.h"
+#include "tzlog_print.h"
+
+/* If you update this, also update sstransaction.h in Secure Kernel */
#define SSTRANSACTION_CHANNEL_SSDEV 1
diff --git a/drivers/misc/artiktee/tzdev.h b/drivers/misc/artiktee/tzdev.h
index 5f86e46c2a8..92bf555f010 100755..100644
--- a/drivers/misc/artiktee/tzdev.h
+++ b/drivers/misc/artiktee/tzdev.h
@@ -31,33 +31,49 @@
#define TZ_IOC_MAGIC 'c'
-#define TZIO_SMC _IOWR(TZ_IOC_MAGIC, 102, struct tzio_message *)
-#define TZIO_WAIT_EVT _IOR(TZ_IOC_MAGIC, 112, unsigned long *)
+#define TZIO_SMC _IOWR(TZ_IOC_MAGIC, 102, struct tzio_message)
#define TZIO_DBG_START _IOR(TZ_IOC_MAGIC, 113, unsigned long)
-#define TZMEM_EXPORT_MEMORY _IOWR(TZ_IOC_MAGIC, 122, struct tzmem_region *)
+#define TZMEM_EXPORT_MEMORY _IOWR(TZ_IOC_MAGIC, 122, struct tzmem_region)
#define TZMEM_RELEASE_MEMORY _IOWR(TZ_IOC_MAGIC, 123, int)
-#define TZMEM_CHECK_MEMORY _IOR(TZ_IOC_MAGIC, 124, struct tzmem_region *)
+#define TZMEM_CHECK_MEMORY _IOR(TZ_IOC_MAGIC, 124, struct tzmem_region)
struct tzio_message {
__u32 type;
__u32 endpoint;
__u32 length;
- int32_t context_id;
- uint32_t timeout_seconds;
- uint32_t boost_flag;
- char payload[];
+ __s32 context_id;
+ __u32 timeout_seconds;
+ __u32 boost_flag;
+ __u8 payload[];
};
struct tzmem_region {
- pid_t pid; /* Memory region owner's PID (in) */
- const void *ptr; /* Memory region start (in) */
- size_t size; /* Memory region size (in) */
- int id; /* Memory region ID (out) */
- unsigned long tee_ctx_id; /* (in) */
- int writable;
+ __s32 pid; /* Memory region owner's PID (in) */
+ const void *ptr; /* Memory region start (in) */
+ __s32 size; /* Memory region size (in) */
+ __s32 id; /* Memory region ID (out) */
+ __u32 tee_ctx_id; /* (in) */
+ __s32 writable;
};
+#ifdef CONFIG_COMPAT
+
+#define TZMEM_COMPAT_EXPORT_MEMORY \
+ _IOWR(TZ_IOC_MAGIC, 122, struct tzmem_region32)
+#define TZMEM_COMPAT_CHECK_MEMORY \
+ _IOR(TZ_IOC_MAGIC, 124, struct tzmem_region32)
+
+struct tzmem_region32 {
+ __s32 pid; /* Memory region owner's PID (in) */
+ __u32 ptr; /* Memory region start (in) */
+ __s32 size; /* Memory region size (in) */
+ __s32 id; /* Memory region ID (out) */
+ __u32 tee_ctx_id; /* (in) */
+ __s32 writable;
+};
+#endif
+
#ifdef __KERNEL__
typedef unsigned long tzdev_page_handle;
@@ -66,19 +82,24 @@ tzdev_page_handle tzdev_alloc_watch_page(void);
void *tzdev_get_virt_addr(tzdev_page_handle h);
phys_addr_t tzdev_get_phys_addr(tzdev_page_handle h);
void tzdev_free_watch_page(tzdev_page_handle pg);
-int tzdev_scm_watch(unsigned long dev_id, unsigned long func_id, unsigned long param1, unsigned long param2, unsigned long param3);
+int tzdev_scm_watch(unsigned long dev_id, unsigned long func_id,
+ unsigned long param1,
+ unsigned long param2,
+ unsigned long param3);
-typedef void (*tzdev_notify_handler_t)(uint32_t target_id, const void *buffer, size_t data_size, void *user_data);
+typedef void (*tzdev_notify_handler_t)(uint32_t target_id,
+ const void *buffer, size_t data_size, void *user_data);
/*
*
* Register notification handler for commands send using scm_send_notification()
*
- * WARNING: Commands may be executed on any thread and any CPU ! Please keep the handler as
- * short possible (for example only notify completion) and avoid waiting on resources.
+ * WARNING: Commands may be executed on any thread and any CPU !
+ * Please keep the handler as short possible
+ * (for example only notify completion) and avoid waiting on resources.
*
- * WARNING 2: Do not send messages from notify handler to SecureOS. This will cause
- * deadlock.
+ * WARNING 2: Do not send messages from notify handler to SecureOS.
+ * This will cause deadlock.
*
*/
int tzdev_register_notify_handler(uint32_t target_id, tzdev_notify_handler_t handler, void *user_data);
diff --git a/drivers/misc/artiktee/tzdev_init.h b/drivers/misc/artiktee/tzdev_init.h
index 2da7317e563..ad863e6ede3 100644
--- a/drivers/misc/artiktee/tzdev_init.h
+++ b/drivers/misc/artiktee/tzdev_init.h
@@ -20,7 +20,6 @@
#define SOURCE_TZDEV_INIT_H_
void tzsys_init(void);
-void tzlog_init(void);
void tzmem_init(void);
int init_storage(void);
void tzio_link_init(void);
diff --git a/drivers/misc/artiktee/tzdev_internal.h b/drivers/misc/artiktee/tzdev_internal.h
index fde66031888..e83429df96f 100644
--- a/drivers/misc/artiktee/tzdev_internal.h
+++ b/drivers/misc/artiktee/tzdev_internal.h
@@ -56,36 +56,6 @@ struct scm_mux_link {
#define WSM_FLAG_PERSIST 0x00000001
-#define TZLOG_ERROR 1 /* Error condition */
-#define TZLOG_WARNING 2 /* Warning condition */
-#define TZLOG_INFO 3 /* Informational */
-#define TZLOG_DEBUG 4 /* Debug-level message */
-
-#define tzlog_print(lvl, fmt, ...) \
- do { \
- if (lvl <= tzlog_loglevel) { \
- switch (lvl) { \
- case TZLOG_ERROR: \
- printk(KERN_ERR "[TZDEV_ERR]%s:"fmt, __func__, ##__VA_ARGS__); \
- break; \
- case TZLOG_WARNING: \
- printk(KERN_WARNING "[TZDEV_WARN]%s:"fmt, __func__, ##__VA_ARGS__); \
- break; \
- case TZLOG_INFO: \
- printk(KERN_INFO "[TZDEV_INFO]%s:"fmt, __func__, ##__VA_ARGS__); \
- break; \
- case TZLOG_DEBUG: \
- printk(KERN_DEBUG "[TZDEV_DBG]%s:"fmt, __func__, ##__VA_ARGS__); \
- break; \
- default: \
- break; \
- } \
- } \
- } while (0)
-
-extern int tzlog_loglevel;
-
-void tzlog_notify(void);
void tzsys_crash_check(void);
struct secos_syspage {
diff --git a/drivers/misc/artiktee/tzdev_main.c b/drivers/misc/artiktee/tzdev_main.c
index 1034c63cce0..464d6ade47b 100644
--- a/drivers/misc/artiktee/tzdev_main.c
+++ b/drivers/misc/artiktee/tzdev_main.c
@@ -48,12 +48,17 @@
#include "tzdev_smc.h"
#include "tzdev_plat.h"
+#ifdef CONFIG_FETCH_TEE_INFO
+#include "tzinfo.h"
+#endif /* !CONFIG_FETCH_TEE_INFO */
+#include "tzlog_core.h"
+#include "tzlog_print.h"
+
#define TZDEV_MAJOR_VERSION "007"
#define TZDEV_MINOR_VERSION "0"
-module_param(tzlog_loglevel, int, 0);
-MODULE_PARM_DESC(tzlog_loglevel,
- "Loglevel of tz driver (8 - debug, 7 - info, 6 - notice, 5 - warning, 4 - error, ...)");
+MODULE_PARM_DESC(default_tzdev_local_log_level,
+ "Loglevel of tz driver (7 - debug, 6 - info, 5 - notice, 4 - warning, 3 - error, ...)");
/*#define CONFIG_TZDEV_CPU_IDLE*/
#ifdef CONFIG_TZDEV_CPU_IDLE
@@ -104,8 +109,6 @@ struct tzdevext_function {
*/
static struct tzdev_ipc_data tzdev_ipc;
-int tzlog_loglevel = TZLOG_INFO;
-
static DEFINE_SPINLOCK(tzio_context_slock);
static DEFINE_IDR(tzio_context_idr);
static LIST_HEAD(tzio_context_delete_q);
@@ -820,8 +823,8 @@ int tzio_message_wait(struct tzio_message *__user msg,
put_user(0, &msg->context_id);
if (context->payload_size) {
- if (copy_to_user
- (msg->payload, context->payload, context->payload_size)) {
+ if (copy_to_user(
+ msg->payload, context->payload, context->payload_size)) {
tzlog_print(TZLOG_ERROR,
"Can't copy data back to userspace\n");
ret = -EFAULT;
@@ -1409,6 +1412,9 @@ static const struct file_operations tzdev_fops = {
.open = tzio_open,
.release = tzio_release,
.mmap = tzio_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tzio_ioctl,
+#endif
.unlocked_ioctl = tzio_ioctl,
.poll = tzio_poll,
.read = tzio_read
@@ -1419,6 +1425,9 @@ static const struct file_operations tzlog_fops = {
.open = tzlog_open,
.read = tzlog_read,
.write = tzlog_write,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tzlog_ioctl,
+#endif
.unlocked_ioctl = tzlog_ioctl,
.release = tzlog_release,
};
@@ -1483,7 +1492,8 @@ static ssize_t tzdev_store(struct kobject *kobj, struct kobj_attribute *attr,
static ssize_t tzlog_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
- return snprintf(buf, 256, "current loglevel = %d\n", tzlog_loglevel);
+ return snprintf(buf, 256, "current loglevel = %d\n",
+ default_tzdev_local_log_level);
}
static ssize_t tzlog_store(struct kobject *kobj, struct kobj_attribute *attr,
@@ -1492,10 +1502,9 @@ static ssize_t tzlog_store(struct kobject *kobj, struct kobj_attribute *attr,
int var;
sscanf(buf, "%d", &var);
- tzlog_print(TZLOG_DEBUG, "Change Loglevel = %d\n", var);
- if (var >= TZLOG_ERROR && var <= TZLOG_DEBUG) {
- tzlog_loglevel = var;
- }
+ tzlog_print(K_DEBUG, "Change Loglevel = %d\n", var);
+ if (var >= K_EMERG && var <= K_DEBUG)
+ default_tzdev_local_log_level = var;
return count;
}
@@ -1506,6 +1515,23 @@ static ssize_t tzmem_show(struct kobject *kobj, struct kobj_attribute *attr,
return snprintf(buf, 256, "TZMEM Show Test\n");
}
+#ifdef CONFIG_FETCH_TEE_INFO
+static ssize_t tzinfo_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ int ret;
+ char *info;
+
+ ret = tzinfo_fetch_info(&info);
+
+ if (ret >= PAGE_SIZE)
+ tzlog_print(TZLOG_WARNING,
+ "Extracted TEE information is suppressed");
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", info);
+}
+#endif /* !CONFIG_FETCH_TEE_INFO */
+
static ssize_t tzmem_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
@@ -1549,6 +1575,11 @@ __ATTR(tzlog, 0660, tzlog_show, tzlog_store);
static struct kobj_attribute tzmem_attr =
__ATTR(tzmem, 0660, tzmem_show, tzmem_store);
+#ifdef CONFIG_FETCH_TEE_INFO
+static struct kobj_attribute tzinfo_attr =
+__ATTR(tzinfo, 0440, tzinfo_show, NULL);
+#endif /* !CONFIG_FETCH_TEE_INFO */
+
#ifndef CONFIG_PSCI
static struct kobj_attribute tzpm_attr =
__ATTR(tzpm, 0660, tzpm_show, tzpm_store);
@@ -1558,6 +1589,9 @@ static struct attribute *tzdev_attrs[] = {
&tzdev_attr.attr,
&tzlog_attr.attr,
&tzmem_attr.attr,
+#ifdef CONFIG_FETCH_TEE_INFO
+ &tzinfo_attr.attr,
+#endif /* !CONFIG_FETCH_TEE_INFO */
#ifndef CONFIG_PSCI
&tzpm_attr.attr,
#endif /* !CONFIG_PSCI */
@@ -1698,6 +1732,15 @@ static int __init init_tzdev(void)
init_storage();
#endif
+#ifdef CONFIG_FETCH_TEE_INFO
+ rc = tzinfo_init();
+ if (rc != 0) {
+ sysfs_remove_file(tzdev_kobj, &tzinfo_attr.attr);
+
+ tzlog_print(TZLOG_WARNING, "Failed to register tzinfo node\n");
+ }
+#endif
+
sstransaction_init();
for_each_possible_cpu(cpu) {
diff --git a/drivers/misc/artiktee/tzdev_plat.c b/drivers/misc/artiktee/tzdev_plat.c
index c39d67dd8ec..f8f4958794c 100644
--- a/drivers/misc/artiktee/tzdev_plat.c
+++ b/drivers/misc/artiktee/tzdev_plat.c
@@ -35,9 +35,8 @@ int plat_preprocess(void)
{
int ret = 0;
- if (pm_qos_request_active(&min_cpu_qos)) {
+ if (pm_qos_request_active(&min_cpu_qos))
pm_qos_update_request(&min_cpu_qos, 1000000);
- }
return ret;
}
@@ -46,9 +45,8 @@ int plat_postprocess(void)
{
int ret = 0;
- if (pm_qos_request_active(&min_cpu_qos)) {
+ if (pm_qos_request_active(&min_cpu_qos))
pm_qos_update_request(&min_cpu_qos, -1);
- }
return ret;
}
diff --git a/drivers/misc/artiktee/tzdev_smc.c b/drivers/misc/artiktee/tzdev_smc.c
index c1eba10c872..d4a6492e99a 100644
--- a/drivers/misc/artiktee/tzdev_smc.c
+++ b/drivers/misc/artiktee/tzdev_smc.c
@@ -23,6 +23,7 @@
#include "tzdev_internal.h"
#include "tzdev_smc.h"
#include "tzpage.h"
+#include "tzlog_print.h"
static inline void __do_call_smc_internal(struct monitor_arguments *args,
struct monitor_result *result)
@@ -287,6 +288,27 @@ int scm_register_phys_wsm(phys_addr_t arg_pfn)
return res.res[0];
}
+#ifdef CONFIG_FETCH_TEE_INFO
+int scm_fetch_tzinfo(int cmd, int arg)
+{
+ struct monitor_arguments args = { 0, };
+ struct monitor_result res = { {0,} };
+
+ args.function_id =
+ SMC_32CALL | SMC_STANDARD_CALL | SMC_ENTITY_SECUREOS |
+ SMC_STD_FETCH_TEE_INFO;
+
+ args.arg[0] = cmd;
+ args.arg[1] = arg;
+ args.arg[2] = 0;
+ args.arg[3] = 0;
+
+ __do_call_smc_internal(&args, &res);
+
+ return res.res[0];
+}
+#endif /* !CONFIG_FETCH_TEE_INFO */
+
#ifndef CONFIG_PSCI
int scm_cpu_suspend(void)
{
diff --git a/drivers/misc/artiktee/tzdev_smc.h b/drivers/misc/artiktee/tzdev_smc.h
index e6a0ed90b7f..26625564172 100644
--- a/drivers/misc/artiktee/tzdev_smc.h
+++ b/drivers/misc/artiktee/tzdev_smc.h
@@ -94,6 +94,10 @@ int scm_watch(unsigned long devfn, unsigned long a0, unsigned long a1,
unsigned long a2);
int scm_register_phys_wsm(phys_addr_t arg_pfn);
+#ifdef CONFIG_FETCH_TEE_INFO
+int scm_fetch_tzinfo(int cmd, int arg);
+#endif /* !CONFIG_FETCH_TEE_INFO */
+
#ifndef CONFIG_PSCI
int scm_cpu_suspend(void);
int scm_cpu_resume(void);
diff --git a/drivers/misc/artiktee/tzinfo.c b/drivers/misc/artiktee/tzinfo.c
new file mode 100644
index 00000000000..e7b749caa07
--- /dev/null
+++ b/drivers/misc/artiktee/tzinfo.c
@@ -0,0 +1,94 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/vmalloc.h>
+
+#include "tzdev_smc.h"
+#include "tzwsm.h"
+#include "tzdev_internal.h"
+#include "log_level_ree.h"
+#include "tzlog_print.h"
+
+#define TZINFO_CMD_REGISTER 0
+#define TZINFO_CMD_FETCH 1
+
+static char *tee_info_data;
+static const char *info_msg = "Not Supported";
+
+int tzinfo_fetch_info(char **buf)
+{
+ int rc;
+
+ if (buf == NULL)
+ return 0;
+
+ rc = scm_fetch_tzinfo(TZINFO_CMD_FETCH, 0);
+
+ *buf = tee_info_data;
+ if (rc < 0)
+ return sizeof(info_msg);
+
+ return rc;
+}
+
+int tzinfo_init(void)
+{
+ void *tzinfo_page;
+ int tzinfo_wsm;
+ int rc;
+
+ /* Single page for tz_info */
+ tzinfo_page = vmalloc(PAGE_SIZE);
+ if (tzinfo_page == NULL) {
+ tzlog_print(K_ERR,
+ "Failed to allocate memory for tzinfo\n");
+ tee_info_data = (char *)info_msg;
+ return -ENOMEM;
+ }
+
+ tee_info_data = (char *)tzinfo_page;
+
+ memset(tee_info_data, 0, PAGE_SIZE);
+
+ tzinfo_wsm =
+ tzwsm_register_kernel_memory(tzinfo_page, PAGE_SIZE,
+ GFP_KERNEL);
+
+ if (tzinfo_wsm < 0) {
+ tzlog_print(K_ERR,
+ "Failed to register WSM for tzinfo\n");
+ vfree(tzinfo_page);
+ tee_info_data = (char *)info_msg;
+ return -EFAULT;
+ }
+
+ rc = scm_fetch_tzinfo(TZINFO_CMD_REGISTER, tzinfo_wsm);
+ if (rc < 0) {
+ tzlog_print(K_WARNING,
+ "Failed to register tzinfo\n");
+ tzwsm_unregister_kernel_memory(tzinfo_wsm);
+ vfree(tzinfo_page);
+ tee_info_data = (char *)info_msg;
+ return -EFAULT;
+ }
+
+ return 0;
+}
diff --git a/drivers/misc/artiktee/tzinfo.h b/drivers/misc/artiktee/tzinfo.h
new file mode 100644
index 00000000000..cf0cef6d9f9
--- /dev/null
+++ b/drivers/misc/artiktee/tzinfo.h
@@ -0,0 +1,25 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#ifndef SOURCE_TZDEV_TZINFO_H_
+#define SOURCE_TZDEV_TZINFO_H_
+
+int tzinfo_init(void);
+int tzinfo_fetch_info(char **buf);
+
+#endif /* SOURCE_TZDEV_TZINFO_H_ */
diff --git a/drivers/misc/artiktee/tzlinkmgr.c b/drivers/misc/artiktee/tzlinkmgr.c
index 1efc05fbfe9..4cdb4aeeff6 100644
--- a/drivers/misc/artiktee/tzlinkmgr.c
+++ b/drivers/misc/artiktee/tzlinkmgr.c
@@ -22,6 +22,7 @@
#include "tzdev_internal.h"
#include "tzpage.h"
#include "tzdev_smc.h"
+#include "tzlog_print.h"
static DEFINE_SPINLOCK(tzio_free_lock);
static LIST_HEAD(tzio_free_links);
diff --git a/drivers/misc/artiktee/tzlog_core.c b/drivers/misc/artiktee/tzlog_core.c
new file mode 100644
index 00000000000..2f3524df5ab
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_core.c
@@ -0,0 +1,300 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/semaphore.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/namei.h>
+#include <linux/path.h>
+#include <linux/vmalloc.h>
+
+#include <asm/barrier.h>
+
+#include "circular_buffer.h"
+#include "tzdev.h"
+#include "tzdev_internal.h"
+#include "tzpage.h"
+#include "tzdev_smc.h"
+#include "ss_file.h"
+
+#include "tzlog_process.h"
+#include "tzlog_core.h"
+
+#ifdef CONFIG_INSTANCE_DEBUG
+#include <linux/vmalloc.h>
+/* it should be change to removing Duplicated code(tzsys.c ) */
+#define ERROR_PARENT_DIR_PATH "/opt/usr/apps/"
+#define ERROR_DIR_NAME_DEPTH1 "save_error_log"
+#define ERROR_DIR_NAME_DEPTH2 "error_log"
+#define ERROR_LOG_PARENT_DIR_PATH "/opt/usr/apps/save_error_log/error_log/"
+#define ERROR_LOG_DIR_NAME "secureos_log"
+#define SYSLOG_ENCRYPT_MEM_SIZE (PAGE_SIZE * 8)
+#endif
+#define TZLOG_TYPE_PURE 1
+#define TZLOG_TYPE_ENCRYPT 2
+
+#define TZLOG_PAGE_ORDER 0
+
+extern void tzdev_notify_worker(void);
+
+static s_tzlog_data log_data = {
+ .ring = NULL,
+ .sem = __SEMAPHORE_INITIALIZER(log_data.sem, 0),
+ .lock = __MUTEX_INITIALIZER(log_data.lock),
+};
+
+#ifdef CONFIG_INSTANCE_DEBUG
+static s_tzlog_data encrypt_log_data = {
+ .ring = NULL,
+};
+#endif
+
+/* it should be change to support creating two depth of folder */
+int tzlog_create_dir(char *parnet_dir_name, char *dir_name)
+{
+ char path[128];
+ struct dentry *dentry;
+ struct path p;
+ int err;
+ struct inode *inode;
+
+ snprintf(path, sizeof(path), "%s%s", parnet_dir_name, dir_name);
+
+ dentry = kern_path_create(AT_FDCWD, path, &p, LOOKUP_DIRECTORY);
+
+ if (IS_ERR(dentry))
+ return PTR_ERR(dentry);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
+ inode = p.dentry->d_inode;
+#else
+ inode = d_inode(p.dentry);
+#endif
+
+ err = vfs_mkdir(inode, dentry, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ done_path_create(&p, dentry);
+ return err;
+}
+
+#ifdef CONFIG_INSTANCE_DEBUG
+int tzlog_output_do_dump(int is_kernel);
+static int tzlog_output_to_error_log(char *data, int data_size,
+ int is_kernel_error)
+{
+ char path[128];
+ unsigned long long T;
+ struct timeval now;
+ tzlog_create_dir(ERROR_PARENT_DIR_PATH, ERROR_DIR_NAME_DEPTH1);
+ snprintf(path, sizeof(path), "%s%s/", ERROR_PARENT_DIR_PATH,
+ ERROR_DIR_NAME_DEPTH1);
+ tzlog_create_dir(path, ERROR_DIR_NAME_DEPTH2);
+ tzlog_create_dir(ERROR_LOG_PARENT_DIR_PATH, ERROR_LOG_DIR_NAME);
+
+ do_gettimeofday(&now);
+ T = (now.tv_sec * 1000ULL) + (now.tv_usec / 1000LL);
+ snprintf(path, sizeof(path), "%s%s/minilog_%s_%lld.log",
+ ERROR_LOG_PARENT_DIR_PATH, ERROR_LOG_DIR_NAME,
+ ((is_kernel_error == 1) ? "os" : "app"), T);
+
+ return ss_file_create_object(path, data, data_size);
+}
+#endif
+
+static int tzlog_worker(void *arg)
+{
+#ifdef CONFIG_INSTANCE_DEBUG
+ int is_need_enc = 0;
+ int enc_ret = 0;
+ int complete = 0;
+ int body_size = 0;
+ char *data = NULL;
+
+ int header_offset = 0;
+ int complete_offset = sizeof(int);
+ int body_offset = sizeof(int) * 2;
+
+ data = (char *)encrypt_log_data.ring;
+ *(int *)((char *)data + complete_offset) = 0;
+ *(int *)((char *)data + header_offset) = 0;
+ is_need_enc = 1;
+#endif
+
+ tzlog_print(TZLOG_DEBUG, "Start tzlog worker thread\n");
+
+ mutex_lock(&log_data.lock);
+ while (!kthread_should_stop()) {
+ int ret;
+
+ do {
+ ret = scm_syslog(log_data.log_wsm_id, TZLOG_TYPE_PURE);
+
+ if (chimera_ring_buffer_readable(log_data.ring)) {
+ /*
+ * We may need to process tasks
+ * after reading back all
+ */
+ tzdev_notify_worker();
+ /* Drain syslog data further */
+ tzlog_transfer_to_tzdaemon(&log_data,
+ PAGE_SIZE <<
+ TZLOG_PAGE_ORDER);
+ tzlog_transfer_to_local(&log_data,
+ PAGE_SIZE <<
+ TZLOG_PAGE_ORDER);
+ chimera_ring_buffer_clear(log_data.ring);
+ }
+#ifdef CONFIG_INSTANCE_DEBUG
+ if (is_need_enc == 1) {
+ *(int *)((char *)data + complete_offset) = 0;
+ *(int *)((char *)data + header_offset) = 0;
+
+ tzlog_print(TZLOG_DEBUG,
+ "tzlog before scm_syslog(encrypt)\n");
+
+ enc_ret =
+ scm_syslog(encrypt_log_data.log_wsm_id,
+ TZLOG_TYPE_ENCRYPT);
+
+ body_size =
+ *(int *)((char *)data + header_offset);
+ complete =
+ *(int *)((char *)data + complete_offset);
+
+ tzlog_print(TZLOG_DEBUG,
+ "tzlog returned %d size = %d(encrypt)\n",
+ complete, body_size);
+
+ if (enc_ret == -1)
+ is_need_enc = 0;
+ else {
+ if (complete & 0x01 && body_size != 0) {
+ tzlog_print(TZLOG_DEBUG,
+ "tzlog process start(encrypt)\n");
+
+ tzdev_notify_worker();
+ tzlog_output_to_error_log(
+ ((char *)data+body_offset),
+ body_size,
+ ((complete & 0x10) ? 1 : 0));
+
+ if (!(complete & 0x10))
+ tzlog_output_do_dump(0);
+
+ tzlog_print(TZLOG_DEBUG,
+ "tzlog process complete(encrypt)\n");
+ } else {
+ tzlog_print(TZLOG_DEBUG,
+ "There's no data in tzlog yet(encrypt)\n");
+ }
+ }
+ }
+#endif
+ } while (ret > 0);
+
+ mutex_unlock(&log_data.lock);
+ ret = down_timeout(&log_data.sem, HZ * 2);
+
+ (void)ret;
+
+ /* Ignore other semaphore down calls */
+ while (down_trylock(&log_data.sem) == 0)
+ ; /* NULL */
+
+ mutex_lock(&log_data.lock);
+ }
+
+ mutex_unlock(&log_data.lock);
+ return 0;
+}
+
+void tzlog_notify(void)
+{
+ tz_syspage->tzlog_data_avail = 0;
+ up(&log_data.sem);
+}
+
+void __init tzlog_init(void)
+{
+ int ret;
+
+#ifdef CONFIG_INSTANCE_DEBUG
+ void *large_page = vmalloc(SYSLOG_ENCRYPT_MEM_SIZE);
+#endif
+
+ ret = init_log_processing_resources();
+ if (ret < 0)
+ panic("Can't register tzlog device (%d)\n", ret);
+
+ log_data.log_page =
+ alloc_pages(GFP_KERNEL | __GFP_ZERO, TZLOG_PAGE_ORDER);
+
+ if (!log_data.log_page)
+ panic("Can't allocate tzlog page\n");
+
+ log_data.ring =
+ chimera_create_ring_buffer_etc(page_address(log_data.log_page),
+ PAGE_SIZE << TZLOG_PAGE_ORDER, 0,
+ GFP_KERNEL);
+
+ tzlog_print(TZLOG_DEBUG, "TZLOG ring at %p\n", log_data.ring);
+ if (log_data.ring != NULL)
+ tzlog_print(TZLOG_DEBUG, "ring size %d\n", log_data.ring->size);
+
+ log_data.log_wsm_id =
+ tzswm_register_tzdev_memory(0, &log_data.log_page,
+ 1U << TZLOG_PAGE_ORDER, GFP_KERNEL, 1);
+
+ if (log_data.log_wsm_id < 0)
+ panic("Can't register log WSM\n");
+
+ tzlog_print(TZLOG_DEBUG, "Registered TZLOG WSM with id %d\n",
+ log_data.log_wsm_id);
+
+#ifdef CONFIG_INSTANCE_DEBUG
+ if (large_page == NULL)
+ panic("Can't allocate tzlog page(encrypt)\n");
+
+ encrypt_log_data.ring = large_page;
+ memset(large_page, 0, SYSLOG_ENCRYPT_MEM_SIZE);
+
+ tzlog_print(TZLOG_DEBUG, "TZLOG ring at %p(encrypt)\n",
+ encrypt_log_data.ring);
+ tzlog_print(TZLOG_DEBUG, "ring size %d(encrypt)\n",
+ (int)SYSLOG_ENCRYPT_MEM_SIZE);
+
+ encrypt_log_data.log_wsm_id =
+ tzwsm_register_kernel_memory(large_page,
+ SYSLOG_ENCRYPT_MEM_SIZE, GFP_KERNEL);
+
+ if (encrypt_log_data.log_wsm_id < 0)
+ panic("Can't register log WSM\n");
+
+ tzlog_print(TZLOG_DEBUG,
+ "Registered TZLOG WSM with id %d(encrypt)\n",
+ encrypt_log_data.log_wsm_id);
+#endif
+ log_data.task = kthread_run(tzlog_worker, NULL, "tzlogd");
+
+ if (IS_ERR(log_data.task))
+ panic("Can't create tzlog worker\n");
+}
diff --git a/drivers/misc/artiktee/tzlog_core.h b/drivers/misc/artiktee/tzlog_core.h
new file mode 100644
index 00000000000..38e55d64eef
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_core.h
@@ -0,0 +1,45 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/semaphore.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/namei.h>
+#include <linux/dcache.h>
+#include <linux/path.h>
+
+#ifndef __TZLOG_CORE_H__
+#define __TZLOG_CORE_H__
+
+typedef struct tzlog_data {
+ int log_wsm_id;
+ struct chimera_ring_buffer *ring;
+ struct semaphore sem;
+ struct task_struct *task;
+ struct mutex lock;
+ struct page *log_page;
+} s_tzlog_data;
+
+void tzlog_notify(void);
+void tzlog_init(void);
+
+#endif
diff --git a/drivers/misc/artiktee/tzlog_print.c b/drivers/misc/artiktee/tzlog_print.c
new file mode 100644
index 00000000000..155b0eb9d6d
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_print.c
@@ -0,0 +1,224 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+
+#include "tzlog_print.h"
+
+kernel_log_level default_tzdev_tee_log_level = TZDEV_TEE_LOG_LEVEL;
+kernel_log_level default_tzdev_local_log_level = TZDEV_LOCAL_LOG_LEVEL;
+
+#define DEFAULT_MEM_SIZE PAGE_SIZE
+/* #define ENABLE_LOG_DEBUG */
+
+static char buf_for_local[DEFAULT_MEM_SIZE];
+static char buf_for_tee[DEFAULT_MEM_SIZE];
+
+static int tzlog_print_common(log_header_info header_info,
+ kernel_log_level level,
+ const char *label,
+ int is_ree,
+ va_list *ap,
+ const char *fmt)
+{
+ int write_len = 0;
+ int buf_size = 0;
+ char *printk_buf = NULL;
+ if (is_ree == 1) {
+ printk_buf = buf_for_local;
+ buf_size = sizeof(buf_for_local);
+ } else {
+ printk_buf = buf_for_tee;
+ buf_size = sizeof(buf_for_tee);
+ }
+
+ if (is_ree == 1) {
+ switch (level) {
+ case K_DEBUG:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][DEBUG]");
+ break;
+ case K_INFO:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][INFO]");
+ break;
+ case K_NOTICE:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][NOTI]");
+ break;
+ case K_WARNING:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][WARN]");
+ break;
+ case K_ERR:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][ERR]");
+ break;
+ case K_CRIT:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][CRIT]");
+ break;
+ case K_ALERT:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][ALERT]");
+ break;
+ case K_EMERG:
+ write_len = snprintf(printk_buf,
+ buf_size, "[REE][TZDEV][EMERG]");
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (header_info) {
+ case SWD_USERMODE:
+ write_len = snprintf(printk_buf,
+ buf_size, "[TEE][TA]");
+ break;
+ case SWD_KERNMODE:
+ write_len = snprintf(printk_buf,
+ buf_size, "[TEE][KERN]");
+ break;
+ default:
+ write_len = snprintf(printk_buf,
+ buf_size, "[TEE]");
+ break;
+ }
+
+ switch (level) {
+ case K_DEBUG:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[DEBUG]");
+ break;
+ case K_INFO:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[INFO]");
+ break;
+ case K_NOTICE:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[NOTI]");
+ break;
+ case K_WARNING:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[WARN]");
+ break;
+ case K_ERR:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[ERR]");
+ break;
+ case K_CRIT:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[CRIT]");
+ break;
+ case K_ALERT:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[ALERT]");
+ break;
+ case K_EMERG:
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[EMERG]");
+ break;
+ default:
+ break;
+ }
+
+ if (label != NULL)
+ write_len += snprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, "[%s]",
+ label);
+ }
+
+ write_len += vsnprintf(printk_buf + write_len,
+ buf_size - 1 - write_len, fmt, *ap);
+
+ if (write_len + 1 >= buf_size) /* buffer is not enough */
+ pr_err("buffer is not enough(ree(%d) / cur : %d )\n",
+ is_ree, buf_size);
+
+ switch (level) {
+ case K_DEBUG:
+ pr_debug("%s", printk_buf);
+ break;
+ case K_INFO:
+ pr_info("%s", printk_buf);
+ break;
+ case K_NOTICE:
+ pr_notice("%s", printk_buf);
+ break;
+ case K_WARNING:
+ pr_warn("%s", printk_buf);
+ break;
+ case K_ERR:
+ pr_err("%s", printk_buf);
+ break;
+ case K_CRIT:
+ pr_crit("%s", printk_buf);
+ break;
+ case K_ALERT:
+ pr_alert("%s", printk_buf);
+ break;
+ case K_EMERG:
+ pr_emerg("%s", printk_buf);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ will be use bit flag for decreasing parameter count.
+ we can change log_header_info to use bit flag
+ */
+void tzlog_print_for_tee(log_header_info header_info,
+ kernel_log_level level,
+ const char *label,
+ const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ if (!(default_tzdev_tee_log_level >= level))
+ return;
+
+ va_start(ap, fmt);
+ ret = tzlog_print_common(header_info, level, label, 0, &ap, fmt);
+ va_end(ap);
+
+#ifdef ENABLE_LOG_DEBUG
+ if (ret == -1)
+ pr_err("tzlog_print_common return err\n");
+#endif
+}
+
+void tzlog_print(kernel_log_level level, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+ if (!(default_tzdev_local_log_level >= level))
+ return;
+
+ va_start(ap, fmt);
+ ret = tzlog_print_common(0, level, NULL, 1, &ap, fmt);
+ va_end(ap);
+
+#ifdef ENABLE_LOG_DEBUG
+ if (ret == -1)
+ pr_err("tzlog_print_common return err\n");
+#endif
+}
diff --git a/drivers/misc/artiktee/tzlog_print.h b/drivers/misc/artiktee/tzlog_print.h
new file mode 100644
index 00000000000..152ee5a3041
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_print.h
@@ -0,0 +1,32 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#ifndef __TZLOG_PRINT_H__
+#define __TZLOG_PRINT_H__
+
+#include "log_level_ree.h"
+
+extern kernel_log_level default_tzdev_local_log_level; /* OutPut */
+
+void tzlog_print(kernel_log_level level, const char *fmt, ...);
+void tzlog_print_for_tee(log_header_info header_info,
+ kernel_log_level level,
+ const char *label,
+ const char *fmt, ...);
+
+#endif
diff --git a/drivers/misc/artiktee/tzlog_process.c b/drivers/misc/artiktee/tzlog_process.c
new file mode 100644
index 00000000000..ee23bea5c70
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_process.c
@@ -0,0 +1,490 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/semaphore.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/namei.h>
+#include <linux/dcache.h>
+#include <linux/path.h>
+#include <linux/vmalloc.h>
+
+#include "circular_buffer.h"
+#include "log_level_ree.h"
+#include "tzlog_process.h"
+#include "tzlog_print.h"
+#include "log_system_api_ext.h"
+
+/*#define ENABLE_LOG_DEBUG*/
+
+#define TZLOG_LOCAL_BUFFERING_SIZE (PAGE_SIZE * 2)
+#define TZLOG_TZDAEMON_BUFFERING_SIZE (PAGE_SIZE * 10)
+#define TZLOG_COPY_TEMP_SIZE 1024
+#define TZLOG_LABEL_SIZE 64
+
+static char buf_label[TZLOG_LABEL_SIZE];
+
+/* Log For Tzdaemon */
+static ssize_t tzlog_read(struct file *filp, char __user *buffer, size_t size,
+ loff_t *off);
+static unsigned int tzlog_poll(struct file *file, poll_table *wait);
+static int tzlog_fasync(int fd, struct file *filp, int on);
+static struct fasync_struct *fasync;
+
+typedef struct tzlog_process {
+ struct chimera_ring_buffer *ring;
+ /* Log For Tzdaemon */
+ struct mutex ring_lock;
+ struct mutex read_lock;
+ wait_queue_head_t empty_wait;
+ wait_queue_head_t full_wait;
+} s_tzlog_process;
+
+static s_tzlog_process log_data_for_local = {
+ .ring = NULL,
+};
+
+static s_tzlog_process log_data_for_tzdaemon = {
+ .ring = NULL,
+ .ring_lock = __MUTEX_INITIALIZER(log_data_for_tzdaemon.ring_lock),
+ /* Log For Tzdaemon */
+ .read_lock = __MUTEX_INITIALIZER(log_data_for_tzdaemon.read_lock),
+ .empty_wait =
+ __WAIT_QUEUE_HEAD_INITIALIZER(log_data_for_tzdaemon.empty_wait),
+ .full_wait =
+ __WAIT_QUEUE_HEAD_INITIALIZER(log_data_for_tzdaemon.full_wait),
+};
+
+/* Log For Tzdaemon */
+static const struct file_operations tzlog_file_operations = {
+ .owner = THIS_MODULE,
+ .read = tzlog_read,
+ .poll = tzlog_poll,
+ .fasync = tzlog_fasync,
+ .llseek = noop_llseek
+};
+
+static struct miscdevice tzlog_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "tzlog",
+ .fops = &tzlog_file_operations,
+ .mode = 0400
+};
+
+int init_log_processing_resources(void)
+{
+ int ret = -1;
+ void *buffering_memory_local =
+ (void *)vmalloc(TZLOG_LOCAL_BUFFERING_SIZE);
+ void *buffering_memory_tzdaemon =
+ (void *)vmalloc(TZLOG_TZDAEMON_BUFFERING_SIZE);
+
+ if (buffering_memory_tzdaemon) {
+ log_data_for_tzdaemon.ring =
+ chimera_create_ring_buffer_etc(buffering_memory_tzdaemon,
+ TZLOG_TZDAEMON_BUFFERING_SIZE,
+ 0, GFP_KERNEL);
+ if (log_data_for_tzdaemon.ring != NULL)
+ chimera_ring_buffer_clear(log_data_for_tzdaemon.ring);
+ } else
+ goto exit_processing_resources;
+
+ if (buffering_memory_local) {
+ log_data_for_local.ring =
+ chimera_create_ring_buffer_etc(buffering_memory_local,
+ TZLOG_LOCAL_BUFFERING_SIZE,
+ 0, GFP_KERNEL);
+ if (log_data_for_local.ring != NULL)
+ chimera_ring_buffer_clear(log_data_for_local.ring);
+ } else
+ goto exit_processing_resources;
+
+ ret = misc_register(&tzlog_device);
+ return ret;
+
+exit_processing_resources:
+ if (buffering_memory_local != NULL)
+ vfree(buffering_memory_local);
+
+ if (buffering_memory_tzdaemon != NULL)
+ vfree(buffering_memory_tzdaemon);
+
+ return ret;
+}
+
+static ssize_t tzlog_read(struct file *filp, char __user *buffer, size_t size,
+ loff_t *off)
+{
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "tzlog_read called\n");
+#endif
+ int error = mutex_lock_interruptible(&log_data_for_tzdaemon.read_lock);
+ ssize_t result;
+
+ if (error < 0)
+ return error;
+
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "TZLOG read %d size = %d, in = %d, out = %d\n",
+ (int)size, log_data_for_tzdaemon.ring->size,
+ log_data_for_tzdaemon.ring->in,
+ log_data_for_tzdaemon.ring->first);
+#endif
+
+ result =
+ chimera_ring_buffer_user_read(log_data_for_tzdaemon.ring,
+ (uint8_t *) buffer, size,
+ TZLOG_TZDAEMON_BUFFERING_SIZE);
+
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO,
+ "TZLOG read result %d size = %d, in = %d, out = %d\n",
+ (int)result, log_data_for_tzdaemon.ring->size,
+ log_data_for_tzdaemon.ring->in,
+ log_data_for_tzdaemon.ring->first);
+#endif
+
+ if (result > 0)
+ wake_up(&log_data_for_tzdaemon.full_wait);
+
+ mutex_unlock(&log_data_for_tzdaemon.read_lock);
+
+ return result;
+}
+
+static unsigned int tzlog_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask;
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "tzlog_poll call\n");
+#endif
+ poll_wait(file, &log_data_for_tzdaemon.empty_wait, wait);
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "tzlog_poll call end\n");
+#endif
+ mask = 0;
+
+ if (chimera_ring_buffer_readable(log_data_for_tzdaemon.ring))
+ mask |= POLLIN | POLLRDNORM;
+
+ return mask;
+}
+
+static int tzlog_fasync(int fd, struct file *filp, int on)
+{
+ return fasync_helper(fd, filp, on, &fasync);
+}
+
+static int tzlog_copy_buffer(s_tzlog_process *dst_data, int dst_buffer_size,
+ s_tzlog_data *src_data, int src_buffer_size)
+{
+ struct iovec iov[2];
+ int i;
+ size_t n_written = 0;
+ int nvec =
+ chimera_ring_buffer_get_vecs(src_data->ring, iov, src_buffer_size);
+ for (i = 0; i < nvec; ++i) {
+ ssize_t written = chimera_ring_buffer_write(dst_data->ring,
+ (const uint8_t *)
+ iov[i].iov_base,
+ iov[i].iov_len,
+ dst_buffer_size);
+
+ if (written < 0) {
+ /* Occur error */
+ break;
+ }
+
+ if (written == 0) {
+ /* Can not write All Log */
+ break;
+ }
+ n_written += written;
+ }
+ return n_written;
+}
+
+void tzlog_transfer_to_tzdaemon(s_tzlog_data *src_data, int src_buffer_size)
+{
+ size_t ret_write = 0;
+ size_t src_size = 0;
+ size_t origin_size = 0;
+ size_t avail = 0;
+
+ src_size = chimera_ring_buffer_readable(src_data->ring);
+ mutex_lock(&log_data_for_tzdaemon.ring_lock);
+
+ /* If we can not completely write, we should be wait for tzdaemon */
+ avail = chimera_ring_buffer_writable(log_data_for_tzdaemon.ring);
+ if (avail < src_size) {
+ wake_up_interruptible(&log_data_for_tzdaemon.empty_wait);
+ kill_fasync(&fasync, SIGIO, POLL_IN);
+
+ /* Wait for tzdaemon's read */
+ {
+ DEFINE_WAIT(__wait);
+ tzlog_print(K_INFO,
+ "tzdaemon log full. wait for drain(src:%d,avail:%d)\n",
+ src_size, avail);
+
+ while (chimera_ring_buffer_writable
+ (log_data_for_tzdaemon.ring) < src_size) {
+ prepare_to_wait(&log_data_for_tzdaemon.
+ full_wait, &__wait,
+ TASK_UNINTERRUPTIBLE);
+ mutex_unlock(&log_data_for_tzdaemon.ring_lock);
+ schedule();
+ mutex_lock(&log_data_for_tzdaemon.ring_lock);
+ }
+ finish_wait(&log_data_for_tzdaemon.full_wait, &__wait);
+ }
+ }
+
+ /* Copy to tzdaemon-ring-buffer from src_data */
+ origin_size = chimera_ring_buffer_readable(log_data_for_tzdaemon.ring);
+ ret_write =
+ tzlog_copy_buffer(&log_data_for_tzdaemon,
+ TZLOG_TZDAEMON_BUFFERING_SIZE, src_data,
+ src_buffer_size);
+ if (src_size != ret_write || ret_write == 0) {
+ int stored_size =
+ chimera_ring_buffer_readable(log_data_for_tzdaemon.ring);
+ if (stored_size - origin_size != src_size) {
+ tzlog_print(K_ERR,
+ "log can loss for tzdaemon(src size : %d, written size: %d stored size : %d)\n",
+ src_size, ret_write, stored_size);
+ }
+ }
+ mutex_unlock(&log_data_for_tzdaemon.ring_lock);
+
+ wake_up_interruptible(&log_data_for_tzdaemon.empty_wait);
+ kill_fasync(&fasync, SIGIO, POLL_IN);
+}
+
+static void tzlog_print_with_header(log_header_type *header, int body_size)
+{
+ char *read_body = NULL;
+ char *temp_read_body = NULL;
+ static char keep_read_body[TZLOG_COPY_TEMP_SIZE] = { 0, };
+ memset(keep_read_body, 0, sizeof(keep_read_body));
+
+ if (sizeof(keep_read_body) - 1 > body_size) {
+ /* If the buffer is sufficient */
+ read_body = keep_read_body;
+ } else {
+ /* If the buffer is not sufficient */
+ temp_read_body = (char *)vmalloc(body_size + 1);
+ if (temp_read_body != NULL) {
+ memset(temp_read_body, 0, body_size + 1);
+ read_body = temp_read_body;
+ }
+ }
+
+ /* output log */
+ if (read_body != NULL) {
+ chimera_ring_buffer_read(log_data_for_local.ring,
+ (uint8_t *) read_body, body_size,
+ TZLOG_LOCAL_BUFFERING_SIZE);
+ if (header != NULL) {
+ memset(buf_label, 0, sizeof(buf_label));
+ if (header->log_label_size <= sizeof(buf_label)) {
+ memcpy(buf_label, read_body,
+ header->log_label_size);
+ }
+ tzlog_print_for_tee(header->log_gen_point,
+ header->log_level, buf_label,
+ (read_body +
+ header->log_label_size));
+ } else
+ tzlog_print_for_tee(0, NO_HEADER_LOG_LEVEL, NULL,
+ read_body);
+ }
+
+ if (temp_read_body != NULL) {
+ vfree(temp_read_body);
+ temp_read_body = NULL;
+ }
+}
+
+void tzlog_transfer_to_local(s_tzlog_data *src_data, int src_buffer_size)
+{
+ size_t ret_write = 0;
+ size_t src_size = 0;
+ size_t ring_data_origin_size = 0;
+ int ring_data_remain_size = 0;
+ int is_need_continue = 0;
+
+ ring_data_origin_size =
+ chimera_ring_buffer_readable(log_data_for_local.ring);
+ src_size = chimera_ring_buffer_readable(src_data->ring);
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "tzdev receive log(%d) ori(%d)\n", src_size,
+ ring_data_origin_size);
+ if (ring_data_origin_size > 0) {
+ char temp_buf[1024] = { 0, };
+ chimera_ring_buffer_peek(log_data_for_local.ring, 0, temp_buf,
+ sizeof(temp_buf),
+ TZLOG_LOCAL_BUFFERING_SIZE);
+ tzlog_print(K_INFO, "tzdev ori log(%s)\n", temp_buf);
+ }
+#endif
+ ret_write =
+ tzlog_copy_buffer(&log_data_for_local, TZLOG_LOCAL_BUFFERING_SIZE,
+ src_data, src_buffer_size);
+ if (src_size != ret_write || ret_write == 0) {
+ int stored_size =
+ chimera_ring_buffer_readable(log_data_for_local.ring);
+ if (stored_size - ring_data_origin_size != src_size) {
+ tzlog_print(K_INFO,
+ "log can loss for tzdev(src size : %d, written size: %d stored size : %d)\n",
+ src_size, ret_write, stored_size);
+ }
+ }
+
+continue_read:
+
+ ring_data_remain_size =
+ chimera_ring_buffer_readable(log_data_for_local.ring);
+ if (ring_data_remain_size >= LHDSIZE) {
+ log_header_type log_header;
+ int head_size = LHDSIZE;
+ int body_size = 0;
+ char header[LHDSIZE + 1] = { 0, };
+ chimera_ring_buffer_peek(log_data_for_local.ring, 0, header,
+ LHDSIZE, TZLOG_LOCAL_BUFFERING_SIZE);
+
+ if (get_log_header(header, &log_header) != 1) {
+ int is_find_header = 0;
+ int find_cnt = 0;
+ int find_max_cnt = ring_data_remain_size - LHDSIZE + 1;
+#ifdef ENABLE_LOG_DEBUG
+ /* Magic Check */
+ tzlog_print(K_INFO, "Magic compare (%c %c %c %c)\n",
+ header[0], header[1], header[2], header[3]);
+#endif
+
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "Header is not compete\n");
+#endif
+ for (; find_cnt < find_max_cnt; find_cnt++) {
+ chimera_ring_buffer_peek(
+ log_data_for_local.ring,
+ find_cnt,
+ header,
+ LHDSIZE,
+ TZLOG_LOCAL_BUFFERING_SIZE);
+ if (get_log_header(header, &log_header) == 1) {
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "Header find\n");
+#endif
+ is_find_header = 1;
+ break;
+ }
+ }
+
+ if (is_find_header == 1) {
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO,
+ "print msg(without magic-case-1)\n");
+#endif
+ tzlog_print_with_header(NULL, find_cnt);
+ goto continue_read;
+ } else {
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO,
+ "print msg(without magic-case-2)\n");
+#endif
+ tzlog_print_with_header(NULL,
+ ring_data_remain_size);
+ }
+ } else {
+#ifdef ENABLE_LOG_DEBUG
+ if (log_header.log_body_size == 0
+ || log_header.log_label_size == 0) {
+ tzlog_print(K_INFO, "Header is compete(%s)\n",
+ header);
+ tzlog_print(K_INFO,
+ "gp is %d / body size is %d / label size is %d / level %d / pid %d\n",
+ log_header.log_gen_point,
+ log_header.log_body_size,
+ log_header.log_label_size,
+ log_header.log_level,
+ log_header.log_pid);
+ }
+#endif
+ is_need_continue = 1;
+ /*
+ * if header ok & body size is enough,
+ * will be processing
+ */
+ body_size = log_header.log_body_size;
+ if (chimera_ring_buffer_readable
+ (log_data_for_local.ring) >=
+ (head_size + body_size)) {
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO, "Can receive body data\n");
+#endif
+ chimera_ring_buffer_read(
+ log_data_for_local.ring,
+ (uint8_t *) header,
+ head_size,
+ TZLOG_LOCAL_BUFFERING_SIZE);
+ tzlog_print_with_header(&log_header, body_size);
+ } else {
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO,
+ "gp is %d / body size is %d / label size is %d / level %d / pid %d\n",
+ log_header.log_gen_point,
+ log_header.log_body_size,
+ log_header.log_label_size,
+ log_header.log_level,
+ log_header.log_pid);
+ tzlog_print(K_INFO,
+ "Header + Body size is not enough(%d,%d)\n",
+ head_size, body_size);
+#endif
+ is_need_continue = 0;
+ }
+ if (is_need_continue == 1)
+ goto continue_read;
+ }
+ } else {
+ if (ring_data_remain_size > 0) {
+ int magic_ret = 0;
+ char header[LHDSIZE + 1] = { 0, };
+ chimera_ring_buffer_peek(log_data_for_local.ring, 0,
+ header, ring_data_remain_size,
+ TZLOG_LOCAL_BUFFERING_SIZE);
+ magic_ret = get_check_magic(header);
+ if (magic_ret == NO_MAGIC) {
+ tzlog_print_with_header(NULL,
+ ring_data_remain_size);
+#ifdef ENABLE_LOG_DEBUG
+ tzlog_print(K_INFO,
+ "Find NO_MAGIC Data - (size : %d) (%s)\n",
+ ring_data_remain_size,
+ (char *)header);
+#endif
+ }
+ }
+ }
+}
diff --git a/drivers/misc/artiktee/tzlog_process.h b/drivers/misc/artiktee/tzlog_process.h
new file mode 100644
index 00000000000..fe07937b17c
--- /dev/null
+++ b/drivers/misc/artiktee/tzlog_process.h
@@ -0,0 +1,29 @@
+/*********************************************************
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd 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 as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#ifndef __TZLOG_PROCESS_H__
+#define __TZLOG_PROCESS_H__
+
+#include "tzlog_core.h"
+
+int init_log_processing_resources(void);
+void tzlog_transfer_to_tzdaemon(s_tzlog_data *src_data, int src_buffer_size);
+void tzlog_transfer_to_local(s_tzlog_data *src_data, int src_buffer_size);
+
+#endif
+
diff --git a/drivers/misc/artiktee/tzmem.c b/drivers/misc/artiktee/tzmem.c
index 3f5232a5478..12006cca8ee 100644
--- a/drivers/misc/artiktee/tzmem.c
+++ b/drivers/misc/artiktee/tzmem.c
@@ -32,6 +32,7 @@
#include "tzdev.h"
#include "tzdev_internal.h"
+#include "tzlog_print.h"
#include "sstransaction.h"
#include "tzpage.h"
#include "tzdev_smc.h"
@@ -117,6 +118,81 @@ static long tzmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}
+#ifdef CONFIG_COMPAT
+static long tzmem_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case TZMEM_COMPAT_EXPORT_MEMORY:
+ {
+ struct tzmem_region32 __user *argp, s;
+
+ argp = (struct tzmem_region32 __user *)arg;
+ if (copy_from_user
+ (&s, argp, sizeof(struct tzmem_region32))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = register_user_memory(file,
+ (unsigned long)s.ptr,
+ s.size,
+ s.tee_ctx_id, s.writable);
+
+ if (ret < 0)
+ break;
+
+ s.pid = current->tgid;
+ s.id = ret;
+ ret = 0;
+
+ if (copy_to_user(argp, &s,
+ sizeof(struct tzmem_region32))) {
+ unregister_user_memory(file, s.id);
+ ret = -EFAULT;
+ break;
+ }
+
+ break;
+ }
+ case TZMEM_RELEASE_MEMORY:
+ {
+ int id;
+
+ if (copy_from_user(&id,
+ (int __user *)arg, sizeof(int))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = unregister_user_memory(file, id);
+ break;
+ }
+ case TZMEM_COMPAT_CHECK_MEMORY:
+ {
+ struct tzmem_region32 __user *argp, s;
+
+ argp = (struct tzmem_region32 __user *)arg;
+ if (copy_from_user
+ (&s, argp, sizeof(struct tzmem_region32))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = verify_client_memory(s.id, s.pid, s.tee_ctx_id);
+ break;
+ }
+ default:
+ tzlog_print(TZLOG_ERROR, "Unknown TZMEM Command: %d\n", cmd);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+#endif
+
struct tzmem_file {
struct list_head nodes;
spinlock_t lock;
@@ -345,6 +421,9 @@ static const struct file_operations tzmem_fops = {
.owner = THIS_MODULE,
.open = tzmem_open,
.release = tzmem_release,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tzmem_compat_ioctl,
+#endif
.unlocked_ioctl = tzmem_ioctl,
};
diff --git a/drivers/misc/artiktee/tzsys.c b/drivers/misc/artiktee/tzsys.c
index 727604e4cef..3ae83076c24 100644
--- a/drivers/misc/artiktee/tzsys.c
+++ b/drivers/misc/artiktee/tzsys.c
@@ -30,16 +30,16 @@
#include "tzdev_internal.h"
#include "tzpage.h"
#include "tzdev_smc.h"
+#include "tzlog_print.h"
+#include "ss_file.h"
-#ifndef CONFIG_VD_RELEASE
-/*#define CONFIG_TZDEV_MINIDUMP*/
-#endif
-
-/*#define CONFIG_INSTANCE_DEBUG*/
#ifdef CONFIG_INSTANCE_DEBUG
+#include <linux/vmalloc.h>
+/* it should be change to removing Duplicated code(tzlog.c ) */
#define CONFIG_TZDEV_MINIDUMP
-#define ERROR_PARENT_DIR_PATH "/opt/usr/apps/save_error_log/"
-#define ERROR_DIR_NAME "error_log"
+#define ERROR_PARENT_DIR_PATH "/opt/usr/apps/"
+#define ERROR_DIR_NAME_DEPTH1 "save_error_log"
+#define ERROR_DIR_NAME_DEPTH2 "error_log"
#define ERROR_DUMP_PARENT_DIR_PATH "/opt/usr/apps/save_error_log/error_log/"
#define ERROR_DUMP_DIR_NAME "secureos_dump"
#endif
@@ -81,7 +81,7 @@ void __init tzsys_init(void)
BUG_ON(rc < 0);
#ifdef CONFIG_TZDEV_MINIDUMP
- tzlog_print(TZLOG_INFO, "Register MiniDump\n");
+ tzlog_print(K_INFO, "Register MiniDump\n");
/* 1MB for minidump */
minipage = vmalloc(MINIDUMP_PAGES * PAGE_SIZE);
@@ -98,7 +98,7 @@ void __init tzsys_init(void)
rc = scm_minidump_register(miniwsm);
- tzlog_print(TZLOG_INFO, "This tzdev has minidump system enabled !!!\n");
+ tzlog_print(K_INFO, "This tzdev has minidump system enabled !!!\n");
#endif
}
@@ -106,8 +106,7 @@ void __init tzsys_init(void)
int tzlog_create_dir(char *parnet_dir_name, char *dir_name);
int tzlog_output_do_dump(int is_kernel)
{
- struct file *file;
- mm_segment_t old_fs;
+ int write_size;
char path[128];
struct timeval now;
unsigned long long T;
@@ -122,11 +121,14 @@ int tzlog_output_do_dump(int is_kernel)
}
if (is_kernel == 1)
- tzlog_print(TZLOG_ERROR, "SecureOS Crash detected\n");
+ tzlog_print(K_ERR, "SecureOS Crash detected\n");
else
- tzlog_print(TZLOG_ERROR, "TA Crash detected\n");
+ tzlog_print(K_ERR, "TA Crash detected\n");
- tzlog_create_dir(ERROR_PARENT_DIR_PATH, ERROR_DIR_NAME);
+ tzlog_create_dir(ERROR_PARENT_DIR_PATH, ERROR_DIR_NAME_DEPTH1);
+ snprintf(path, sizeof(path), "%s%s/",
+ ERROR_PARENT_DIR_PATH, ERROR_DIR_NAME_DEPTH1);
+ tzlog_create_dir(path, ERROR_DIR_NAME_DEPTH2);
tzlog_create_dir(ERROR_DUMP_PARENT_DIR_PATH, ERROR_DUMP_DIR_NAME);
do_gettimeofday(&now);
@@ -137,60 +139,43 @@ int tzlog_output_do_dump(int is_kernel)
ERROR_DUMP_PARENT_DIR_PATH, ERROR_DUMP_DIR_NAME,
((is_kernel == 1) ? "os" : "app"), T);
- file = filp_open(path, O_CREAT | O_RDWR | O_SYNC, 0600);
-
- if (IS_ERR(file)) {
- if (is_kernel == 1)
- tzlog_print(TZLOG_ERROR,
- "error occured while opening file %s, exiting...\n",
- path);
- else
- tzlog_print(TZLOG_DEBUG,
- "error occured while opening file %s, exiting...\n",
- path);
+ write_size = ss_file_create_object(path, tz_minidump_data,
+ tz_syspage->minidump_size);
+
+ if (write_size <= 0) {
+ tzlog_print(K_ERR,
+ "error occured while opening file %s, exiting...\n",
+ path);
goto out;
}
if (is_kernel == 1)
- tzlog_print(TZLOG_ERROR, "Writing SecureOS minidump to %s\n",
- path);
+ tzlog_print(K_ERR, "Writing SecureOS minidump to %s\n", path);
else
- tzlog_print(TZLOG_DEBUG, "Writing TA minidump to %s\n", path);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- file->f_op->llseek(file, 0, SEEK_SET);
- file->f_op->write(file, tz_minidump_data, tz_syspage->minidump_size,
- &file->f_pos);
-
- set_fs(old_fs);
-
- vfs_fsync(file, 0);
- vfs_fsync(file, 1);
-
- filp_close(file, NULL);
+ tzlog_print(K_INFO, "Writing TA minidump to %s\n", path);
if (is_kernel == 1)
- tzlog_print(TZLOG_ERROR, "Minidump stored %u bytes\n",
+ tzlog_print(K_ERR, "Minidump stored %u bytes\n",
tz_syspage->minidump_size);
else
- tzlog_print(TZLOG_DEBUG,
+ tzlog_print(K_INFO,
"Minidump TA stored %u bytespc)(uuid:%s)\n",
tz_syspage->minidump_size, tz_syspage->uid);
memset(tz_minidump_data, 0, tz_syspage->minidump_size);
- tz_syspage->minidump_size = 0;
+ memset(tz_syspage->uid, 0, sizeof(tz_syspage->uid));
#ifdef CONFIG_INSTANCE_DEBUG
#ifdef CONFIG_CALL_SAVELOG
- if (is_kernel == 1) {
+ if (is_kernel == 1)
set_kpi_fault(0, 0, "main", "TrustWare", "TZ");
- } else {
+ else
set_kpi_fault(0, 0, "main", tz_syspage->uid, "TZ");
- }
#endif
#endif
+
+ /* End of writing the dump file */
+ tz_syspage->minidump_size = 0;
out:
return 0;
}
@@ -226,7 +211,7 @@ void tzsys_crash_check(void)
if (!IS_ERR(task)) {
wake_up_process(task);
} else {
- tzlog_print(TZLOG_ERROR,
+ tzlog_print(K_ERR,
"Can't spawn worker for minidump. Execute now\n");
tz_crash_worker(NULL);
}
diff --git a/drivers/misc/artiktee/tzwsm.c b/drivers/misc/artiktee/tzwsm.c
index bbe6d3ce73f..73c1e19a853 100644
--- a/drivers/misc/artiktee/tzwsm.c
+++ b/drivers/misc/artiktee/tzwsm.c
@@ -23,10 +23,10 @@
#include <linux/uaccess.h>
#include <linux/slab.h>
#include "tzdev.h"
-#include "tzdev_internal.h"
#include "tzpage.h"
#include "tzdev_smc.h"
#include "wsm.h"
+#include "tzlog_print.h"
int tzswm_register_tzdev_memory(uint64_t ctx_id, struct page **pages,
size_t num_pages, gfp_t gfp, int for_kernel)