1/*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Decription: TEE Logging Subsystem, read the tee os log from log memory
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include "tlogger.h"
15#include <linux/miscdevice.h>
16#include <linux/uaccess.h>
17#include <linux/poll.h>
18#include <linux/slab.h>
19#include <linux/version.h>
20#include <linux/delay.h>
21#include <asm/ioctls.h>
22#include <linux/syscalls.h>
23#include <securec.h>
24#include <asm/io.h>
25#include "smc_smp.h"
26#include "mailbox_mempool.h"
27#include "teek_client_constants.h"
28#include "tc_ns_client.h"
29#include "teek_ns_client.h"
30#include "log_cfg_api.h"
31#include "tc_ns_log.h"
32#include "ko_adapt.h"
33#include "internal_functions.h"
34#ifdef CONFIG_LOG_POOL
35#include "shared_mem.h"
36#endif
37#ifdef CONFIG_TEE_REBOOT
38#include "reboot.h"
39#endif
40
41/* for log item ----------------------------------- */
42#define LOG_ITEM_MAGIC		  	0x5A5A
43#define LOG_ITEM_LEN_ALIGN	  	64
44#define LOG_ITEM_MAX_LEN		1024
45#define LOG_READ_STATUS_ERROR   0x000FFFF
46
47/* =================================================== */
48#define LOGGER_LOG_TEEOS		"teelog" /* tee os log */
49#define LOGGERIOCTL			 	0xBE /* for ioctl */
50
51#define DUMP_START_MAGIC "Dump SPI notification"
52#define DUMP_END_MAGIC "Dump task states END"
53
54#define GET_VERSION_BASE	   5
55#define SET_READERPOS_CUR_BASE 6
56#define SET_TLOGCAT_STAT_BASE  7
57#define GET_TLOGCAT_STAT_BASE  8
58
59/* get tee verison */
60#define MAX_TEE_VERSION_LEN	   256
61#define TEELOGGER_GET_VERSION \
62	_IOR(LOGGERIOCTL, GET_VERSION_BASE, char[MAX_TEE_VERSION_LEN])
63/* set the log reader pos to current pos */
64#define TEELOGGER_SET_READERPOS_CUR \
65	_IO(LOGGERIOCTL, SET_READERPOS_CUR_BASE)
66#define TEELOGGER_SET_TLOGCAT_STAT \
67	_IO(LOGGERIOCTL, SET_TLOGCAT_STAT_BASE)
68#define TEELOGGER_GET_TLOGCAT_STAT \
69	_IO(LOGGERIOCTL, GET_TLOGCAT_STAT_BASE)
70
71#ifdef CONFIG_LOG_POOL
72struct teelogger_log_pool {
73	uint64_t addr;
74	uint64_t size;
75};
76
77#define GET_LOG_POOL_BASE 9
78#define LOG_POOL_APPEND_BASE 10
79
80#define TEELOGGER_GET_LOG_POOL \
81	_IOWR(LOGGERIOCTL, GET_LOG_POOL_BASE, uint64_t)
82#define TEELOGGER_LOG_POOL_APPEND \
83	_IOWR(LOGGERIOCTL, LOG_POOL_APPEND_BASE, struct teelogger_log_pool)
84#endif
85
86int g_tlogcat_f = 0;
87
88#ifndef CONFIG_TEE_LOG_ACHIVE_PATH
89#define CONFIG_TEE_LOG_ACHIVE_PATH "/data/log/tee/last_teemsg"
90#endif
91#define TEE_LOG_FILE_NAME_MAX 256
92
93uint32_t g_last_read_offset = 0;
94
95#define NEVER_USED_LEN 32U
96#define LOG_ITEM_RESERVED_LEN 1U
97
98/* 64 byte head + user log */
99struct log_item {
100	unsigned char never_used[NEVER_USED_LEN];
101	unsigned short magic;
102	unsigned short reserved0;
103	uint32_t serial_no;
104	unsigned short real_len; /* log real len */
105	unsigned short buffer_len; /* log buffer's len, multiple of 32 bytes */
106	unsigned char uuid[UUID_LEN];
107	unsigned char log_source_type;
108	unsigned char reserved[LOG_ITEM_RESERVED_LEN];
109	unsigned char log_level;
110	unsigned char new_line; /* '\n' char, easy viewing log in bbox.bin file */
111	unsigned char log_buffer[];
112};
113
114/* --- for log mem --------------------------------- */
115#define TEMP_LOG_MEM_SIZE		   (10 * SZ_1K)
116
117#define LOG_BUFFER_RESERVED_LEN	   11U
118#define VERSION_INFO_LEN		   156U
119
120/*
121 * Log's buffer flag info, size: 64 bytes head + 156 bytes's version info.
122 * For filed description:
123 * last_pos : current log's end position, last log's start position.
124 * write_loops: Write cyclically. Init value is 0, when memory is used
125 *			  up, the value add 1.
126 */
127struct log_buffer_flag {
128	uint32_t reserved0;
129	uint32_t last_pos;
130	uint32_t write_loops;
131	uint32_t log_level;
132	/* [0] is magic failed, [1] is serial_no failed, used fior log retention feature */
133	uint32_t reserved[LOG_BUFFER_RESERVED_LEN];
134	uint32_t max_len;
135	unsigned char version_info[VERSION_INFO_LEN];
136};
137
138struct log_buffer {
139	struct log_buffer_flag flag;
140	unsigned char buffer_start[];
141};
142
143static struct log_buffer *g_log_buffer = NULL;
144
145struct tlogger_log {
146	unsigned char *buffer_info; /* ring buffer info */
147	struct mutex mutex_info; /* this mutex protects buffer_info */
148	wait_queue_head_t wait_queue_head; /* wait queue head for reader */
149	struct list_head logs; /* log channels list */
150	struct miscdevice misc_device; /* misc device log */
151	struct list_head readers; /* log's readers */
152};
153
154static LIST_HEAD(m_log_list);
155
156struct tlogger_reader {
157	struct tlogger_log *log; /* tlogger_log info data */
158	struct list_head list; /* log entry in tlogger_log's list */
159	/* Current reading position, start position of next read again */
160	uint32_t r_off;
161	uint32_t r_loops;
162	uint32_t r_sn;
163	uint32_t r_failtimes;
164	uint32_t r_from_cur;
165	uint32_t r_is_tlogf;
166	bool r_all; /* whether this reader can read all entries */
167	uint32_t r_ver;
168};
169
170static uint32_t g_log_mem_len = 0;
171static uint32_t g_tlogcat_count = 0;
172static struct tlogger_log *g_log;
173
174static struct tlogger_log *get_reader_log(const struct file *file)
175{
176	struct tlogger_reader *reader = NULL;
177
178	reader = file->private_data;
179	if (!reader)
180		return NULL;
181
182	return reader->log;
183}
184
185static bool check_log_item_validite(const struct log_item *item,
186	uint32_t item_max_size)
187{
188	bool con = (item && (item->magic == LOG_ITEM_MAGIC) &&
189		(item->buffer_len > 0) &&
190		(item->real_len > 0) &&
191		(item->buffer_len % LOG_ITEM_LEN_ALIGN == 0) &&
192		(item->real_len <= item->buffer_len) &&
193		((item->buffer_len - item->real_len) < LOG_ITEM_LEN_ALIGN) &&
194		(item->buffer_len + sizeof(*item) <= item_max_size));
195
196	return con;
197}
198
199static struct log_item *get_next_log_item(const unsigned char *buffer_start,
200	uint32_t max_len, uint32_t read_pos, uint32_t scope_len, uint32_t *pos)
201{
202	uint32_t i = 0;
203	struct log_item *item = NULL;
204	uint32_t max_size;
205
206	if ((read_pos + scope_len) > max_len)
207		return NULL;
208
209	while ((i + sizeof(*item) + LOG_ITEM_LEN_ALIGN) <= scope_len) {
210		*pos = read_pos + i;
211		item = (struct log_item *)(uintptr_t)(buffer_start + read_pos + i);
212		max_size = (((scope_len - i) > LOG_ITEM_MAX_LEN) ?
213			LOG_ITEM_MAX_LEN : (scope_len - i));
214		if (check_log_item_validite(item, max_size))
215			break;
216
217		i += LOG_ITEM_LEN_ALIGN;
218		item = NULL;
219	}
220
221	return item;
222}
223
224struct reader_position {
225	const unsigned char *buffer_start;
226	uint32_t max_len;
227	uint32_t start_pos;
228	uint32_t end_pos;
229};
230
231static uint32_t parse_log_item(char __user *buf, size_t count,
232	struct reader_position *position, uint32_t *read_off,
233	bool *user_buffer_left)
234{
235	struct log_item *next_item = NULL;
236	size_t buf_left;
237	uint32_t buf_written;
238	uint32_t item_len;
239	bool con = false;
240	uint32_t start_pos = position->start_pos;
241
242	buf_written = 0;
243	buf_left = count;
244
245	con = (!read_off || !position->buffer_start);
246	if (con)
247		return buf_written;
248
249	*user_buffer_left = true;
250	while (start_pos < position->end_pos) {
251		next_item = get_next_log_item(position->buffer_start,
252			position->max_len, start_pos,
253			position->end_pos - start_pos, &start_pos);
254		if (!next_item)
255			break;
256
257		/* copy to user */
258		item_len = next_item->buffer_len + sizeof(*next_item);
259		if (buf_left < item_len) {
260			*user_buffer_left = false;
261			break;
262		}
263
264		start_pos += item_len;
265		if (copy_to_user(buf + buf_written,
266			(void *)next_item, item_len) != 0)
267			tloge("copy failed, item len %u\n", item_len);
268		buf_written += item_len;
269		buf_left -= item_len;
270	}
271
272	*read_off = start_pos;
273	return buf_written;
274}
275
276static ssize_t get_buffer_info(struct tlogger_reader *reader,
277	struct log_buffer_flag *buffer_flag, struct log_buffer **log_buffer)
278{
279	struct tlogger_log *log = NULL;
280	errno_t ret;
281	struct log_buffer *buffer_tmp = NULL;
282
283	log = reader->log;
284	if (!log)
285		return -EINVAL;
286
287	buffer_tmp = (struct log_buffer*)log->buffer_info;
288	if (!buffer_tmp)
289		return -EINVAL;
290
291	__asm__ volatile ("isb");
292	__asm__ volatile ("dsb sy");
293
294	mutex_lock(&log->mutex_info);
295	ret = memcpy_s(buffer_flag, sizeof(*buffer_flag), &buffer_tmp->flag,
296		sizeof(buffer_tmp->flag));
297	mutex_unlock(&log->mutex_info);
298	if (ret != 0) {
299		tloge("memcpy failed %d\n", ret);
300		return -EAGAIN;
301	}
302
303	*log_buffer = buffer_tmp;
304	return 0;
305}
306
307#define LOG_BUFFER_MAX_LEN	  0x100000
308
309static ssize_t get_last_read_pos(struct log_buffer_flag *log_flag,
310	const struct tlogger_reader *reader, uint32_t *log_last_pos, uint32_t *is_read)
311{
312	uint32_t buffer_max_len = g_log_mem_len - sizeof(*g_log_buffer);
313
314	*is_read = 0;
315
316	if (buffer_max_len > LOG_BUFFER_MAX_LEN)
317		return -EINVAL;
318
319	*log_last_pos = log_flag->last_pos;
320	if (*log_last_pos == reader->r_off &&
321		log_flag->write_loops == reader->r_loops)
322		return 0;
323
324	if (log_flag->max_len < *log_last_pos ||
325		log_flag->max_len > buffer_max_len) {
326		tloge("invalid data maxlen %x pos %x\n",
327			log_flag->max_len, *log_last_pos);
328		return -EFAULT;
329	}
330
331	if (reader->r_off > log_flag->max_len) {
332		tloge("invalid data roff %x maxlen %x\n",
333			reader->r_off, log_flag->max_len);
334		return -EFAULT;
335	}
336
337	*is_read = 1;
338	return 0;
339}
340
341static void set_reader_position(struct reader_position *position,
342	const unsigned char *buffer_start, uint32_t max_len, uint32_t start_pos, uint32_t end_pos)
343{
344	position->buffer_start = buffer_start;
345	position->max_len = max_len;
346	position->start_pos = start_pos;
347	position->end_pos = end_pos;
348}
349
350static ssize_t proc_read_ret(uint32_t buf_written,
351	const struct tlogger_reader *reader)
352{
353	ssize_t ret;
354	if (buf_written == 0) {
355		ret = 0;
356	} else {
357		ret = buf_written;
358		tlogd("read length %u\n", buf_written);
359		g_last_read_offset = reader->r_off;
360	}
361	return ret;
362}
363
364static ssize_t check_read_params(const struct file *file,
365	const char __user *buf, size_t count)
366{
367	if (count < LOG_ITEM_MAX_LEN)
368		return -EINVAL;
369
370	if (!file || !buf)
371		return -EINVAL;
372
373	return 0;
374}
375
376/*
377 * If the sequence number of the last read position is smaller
378 * than the current minimum sequence number, the last read
379 * position is overwritten. And this time read data from
380 * minimum number, or read data from last position.
381 */
382static ssize_t trigger_parse_log(char __user *buf, size_t count,
383	uint32_t log_last_pos, struct log_buffer *log_buffer,
384	struct tlogger_reader *reader)
385{
386	bool user_buffer_left = false;
387	uint32_t buf_written;
388	struct reader_position position = {0};
389	struct log_buffer_flag *buffer_flag = &(log_buffer->flag);
390
391	if (buffer_flag->write_loops == reader->r_loops) {
392		set_reader_position(&position, log_buffer->buffer_start,
393			buffer_flag->max_len, reader->r_off, log_last_pos);
394
395		buf_written = parse_log_item(buf, count, &position,
396			&reader->r_off, &user_buffer_left);
397
398		return proc_read_ret(buf_written, reader);
399	}
400
401	if (buffer_flag->write_loops > (reader->r_loops +1) ||
402		((buffer_flag->write_loops == (reader->r_loops + 1)) &&
403		(reader->r_off < log_last_pos))) {
404		reader->r_off = log_last_pos;
405		reader->r_loops = buffer_flag->write_loops - 1;
406	}
407
408	set_reader_position(&position, log_buffer->buffer_start,
409		buffer_flag->max_len, reader->r_off, buffer_flag->max_len);
410
411	buf_written = parse_log_item(buf, count, &position,
412		&reader->r_off, &user_buffer_left);
413
414	if (count > buf_written && user_buffer_left) {
415		set_reader_position(&position, log_buffer->buffer_start,
416			buffer_flag->max_len, 0, log_last_pos);
417
418		buf_written += parse_log_item(buf + buf_written,
419			count - buf_written, &position,
420			&reader->r_off, &user_buffer_left);
421
422		reader->r_loops = buffer_flag->write_loops;
423	}
424
425	return proc_read_ret(buf_written, reader);
426}
427
428static ssize_t process_tlogger_read(struct file *file,
429	char __user *buf, size_t count, loff_t *pos)
430{
431	struct tlogger_reader *reader = NULL;
432	struct log_buffer *log_buffer = NULL;
433	ssize_t ret;
434	uint32_t last_pos;
435	uint32_t is_read;
436	struct log_buffer_flag buffer_flag;
437
438	(void)pos;
439
440	ret = check_read_params(file, buf, count);
441	if (ret != 0)
442		return ret;
443
444	reader = file->private_data;
445	if (!reader)
446		return -EINVAL;
447
448	ret = get_buffer_info(reader, &buffer_flag, &log_buffer);
449	if (ret != 0)
450		return ret;
451
452	ret = get_last_read_pos(&buffer_flag, reader, &last_pos, &is_read);
453	if (is_read == 0)
454		return ret;
455
456	return trigger_parse_log(buf, count, last_pos, log_buffer, reader);
457}
458
459void tz_log_write(void)
460{
461	struct log_buffer *log_buffer = NULL;
462
463	if (!g_log)
464		return;
465
466	log_buffer = (struct log_buffer*)g_log->buffer_info;
467	if (!log_buffer)
468		return;
469
470	if (g_last_read_offset != log_buffer->flag.last_pos) {
471		tlogd("wake up write tz log\n");
472		wake_up_interruptible(&g_log->wait_queue_head);
473	}
474
475	return;
476}
477
478static struct tlogger_log *get_tlogger_log_by_minor(int minor)
479{
480	struct tlogger_log *log = NULL;
481
482	list_for_each_entry(log, &m_log_list, logs) {
483		if (log->misc_device.minor == minor)
484			return log;
485	}
486
487	return NULL;
488}
489
490static int process_tlogger_open(struct inode *inode,
491	struct file *file)
492{
493	struct tlogger_log *log = NULL;
494	int ret;
495	struct tlogger_reader *reader = NULL;
496
497	tlogd("open logger open ++\n");
498	/* not support seek */
499	ret = nonseekable_open(inode, file);
500	if (ret != 0)
501		return ret;
502
503	tlogd("Before get log from minor\n");
504	log = get_tlogger_log_by_minor(MINOR(inode->i_rdev));
505	if (!log)
506		return -ENODEV;
507
508	reader = kmalloc(sizeof(*reader), GFP_KERNEL);
509	if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)reader))
510		return -ENOMEM;
511
512	reader->log = log;
513	reader->r_all = true;
514	reader->r_off = 0;
515	reader->r_loops = 0;
516	reader->r_sn = 0;
517	reader->r_failtimes = 0;
518	reader->r_is_tlogf = 0;
519	reader ->r_from_cur = 0;
520
521	INIT_LIST_HEAD(&reader->list);
522
523	mutex_lock(&log->mutex_info);
524	list_add_tail(&reader->list, &log->readers);
525	g_tlogcat_count++;
526	mutex_unlock(&log->mutex_info);
527
528	file->private_data = reader;
529	tlogd("tlogcat count %u\n", g_tlogcat_count);
530#ifdef CONFIG_TEE_REBOOT
531	get_tlogcat_pid();
532#endif
533	return 0;
534}
535
536static int process_tlogger_release(struct inode *ignored,
537	struct file *file)
538{
539	struct tlogger_reader *reader = NULL;
540	struct tlogger_log *log = NULL;
541
542	(void)ignored;
543
544	tlogd("logger_release ++\n");
545
546	if (!file)
547		return -1;
548
549	reader = file->private_data;
550	if (!reader) {
551		tloge("reader is null\n");
552		return -1;
553	}
554
555	log = reader->log;
556	if (!log) {
557		tloge("log is null\n");
558		return -1;
559	}
560
561	mutex_lock(&log->mutex_info);
562	list_del(&reader->list);
563	if (g_tlogcat_count >= 1)
564		g_tlogcat_count--;
565	mutex_unlock(&log->mutex_info);
566
567	tlogd("logger_release r_is_tlogf-%u\n", reader->r_is_tlogf);
568
569	if (reader->r_is_tlogf != 0)
570		g_tlogcat_f = 0;
571
572	kfree(reader);
573	tlogd("tlogcat count %u\n", g_tlogcat_count);
574	return 0;
575}
576
577static unsigned int process_tlogger_poll(struct file *file,
578	poll_table *wait)
579{
580	struct tlogger_reader *reader = NULL;
581	struct tlogger_log *log = NULL;
582	struct log_buffer *buffer = NULL;
583	uint32_t ret = POLLOUT | POLLWRNORM;
584
585	tlogd("logger_poll ++\n");
586	if (!file) {
587		tloge("file is null\n");
588		return ret;
589	}
590
591	reader = file->private_data;
592	if (!reader) {
593		tloge("the private data is null\n");
594		return ret;
595	}
596
597	log = reader->log;
598	if (!log) {
599		tloge("log is null\n");
600		return ret;
601	}
602
603	buffer = (struct log_buffer*)log->buffer_info;
604	if (!buffer) {
605		tloge("buffer is null\n");
606		return ret;
607	}
608
609	poll_wait(file, &log->wait_queue_head, wait);
610
611	if (buffer->flag.last_pos != reader->r_off)
612		ret |= POLLIN | POLLRDNORM;
613
614	return ret;
615}
616
617#define SET_READ_POS   1U
618static void set_reader_cur_pos(const struct file *file)
619{
620	struct tlogger_reader *reader = NULL;
621	struct tlogger_log *log = NULL;
622	struct log_buffer *buffer = NULL;
623
624	reader = file->private_data;
625	if (!reader)
626		return;
627
628	log = reader->log;
629	if (!log)
630		return;
631
632	buffer = (struct log_buffer*)log->buffer_info;
633	if (!buffer)
634		return;
635
636	reader->r_from_cur = SET_READ_POS;
637	reader->r_off = buffer->flag.last_pos;
638	reader->r_loops = buffer->flag.write_loops;
639}
640
641static void set_tlogcat_f_stat(const struct file *file)
642{
643	struct tlogger_reader *reader = NULL;
644
645	if (!file)
646		return;
647
648	reader = file->private_data;
649	if (!reader)
650		return;
651
652	reader->r_is_tlogf = 1;
653	g_tlogcat_f = 1;
654
655	tlogi("set tlogcat_f-%d\n", g_tlogcat_f);
656	return;
657}
658
659static int get_tlogcat_f_stat(void)
660{
661	tlogi("get tlogcat_f-%d\n", g_tlogcat_f);
662	return g_tlogcat_f;
663}
664
665static int check_user_arg(unsigned long arg, size_t arg_len)
666{
667#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 18) || \
668	LINUX_VERSION_CODE == KERNEL_VERSION(4, 19, 71))
669	return (int)access_ok(VERIFY_READ,
670		(void __user *)(uintptr_t)arg, arg_len);
671#else
672	return (int)access_ok((void __user *)(uintptr_t)arg, arg_len);
673#endif
674}
675
676static int get_teeos_version(uint32_t cmd, unsigned long arg)
677{
678	int ret;
679
680	if ((_IOC_DIR(cmd) & _IOC_READ) == 0) {
681		tloge("check get version cmd failed\n");
682		return -1;
683	}
684
685	ret = check_user_arg(arg,
686		sizeof(g_log_buffer->flag.version_info));
687	if (ret == 0) {
688		tloge("check version info arg failed\n");
689		return -1;
690	}
691
692	if (copy_to_user((void __user *)(uintptr_t)arg,
693		(void *)g_log_buffer->flag.version_info,
694		sizeof(g_log_buffer->flag.version_info)) != 0) {
695		tloge("version info copy failed\n");
696		return -1;
697	}
698
699	return 0;
700}
701
702#ifdef CONFIG_LOG_POOL
703#define LOG_POOL_SIZE 0x80000UL
704#define LOG_POOL_ITEM_MAX_LEN 384
705#define HALF_DIV_NUM 2
706
707static DEFINE_MUTEX(g_log_pool_lock);
708static uint64_t g_log_pool_va = 0;
709static uint64_t g_log_pool_size = 0;
710static uint32_t g_logserialno = 0;
711
712static int get_log_pool(void *argp)
713{
714	uint64_t sz = 0;
715
716	if (argp == NULL) {
717		tloge("invalid params\n");
718		return -1;
719	}
720	sz = get_log_mem_size() / HALF_DIV_NUM;
721	if (sz != LOG_POOL_SIZE) {
722		tloge("log pool size error\n");
723		return -1;
724	}
725	if (copy_to_user(argp, &sz, sizeof(uint64_t)) != 0) {
726		tloge("copy to user failed\n");
727		return -1;
728	}
729
730	return 0;
731}
732
733static int log_pool_check(void)
734{
735	if (g_log_pool_size != LOG_POOL_SIZE) {
736		tloge("log pool size error\n");
737		g_log_pool_size = 0;
738		return -1;
739	}
740
741	if (g_log_pool_va == 0 || (UINT64_MAX - g_log_pool_va) < g_log_pool_size) {
742		tloge("log pool addr error\n");
743		g_log_pool_va = 0;
744		return -1;
745	}
746
747	return 0;
748}
749
750static int log_pool_item_check(struct log_item *item, struct teelogger_log_pool pool_item)
751{
752	if (item->magic != LOG_ITEM_MAGIC || item->buffer_len == 0 || item->real_len == 0||
753		item->buffer_len % LOG_ITEM_LEN_ALIGN != 0 || item->real_len > item->buffer_len ||
754		(item->buffer_len - item->real_len) >= (uint16_t)LOG_ITEM_LEN_ALIGN ||
755		(uint64_t)(item->buffer_len + sizeof(struct log_item)) > pool_item.size)
756		return -1;
757
758	return 0;
759}
760
761static int log_pool_append(void *argp)
762{
763	struct teelogger_log_pool pool_item = {0};
764	struct log_buffer *pool_buffer = NULL;
765	struct log_item *item = NULL;
766	if (argp == NULL || log_pool_check() != 0) {
767		tloge("invalid params, g_log_pool_va or g_log_pool_size\n");
768		return -1;
769	}
770	if (copy_from_user((void *)&pool_item, argp, sizeof(struct teelogger_log_pool)) != 0) {
771		tloge("pool_item copy from user error\n");
772		return -1;
773	}
774	if ((uint64_t)LOG_POOL_ITEM_MAX_LEN < pool_item.size || pool_item.size < (uint64_t)sizeof(struct log_item) ||
775		pool_item.addr == 0 || UINT64_MAX - pool_item.addr < pool_item.size) {
776		tloge("pool_item addr or size error\n");
777		return -1;
778	}
779
780	mutex_lock(&g_log_pool_lock);
781	pool_buffer = (struct log_buffer *)(uintptr_t)g_log_pool_va;
782	if (pool_buffer == NULL || (uint64_t)(pool_buffer->flag).last_pos > g_log_pool_size ||
783		((uint64_t)sizeof(struct log_buffer) + (uint64_t)(pool_buffer->flag).last_pos) > g_log_pool_size) {
784		tloge("pool_buffer error\n");
785		mutex_unlock(&g_log_pool_lock);
786		return -1;
787	}
788	/* restart from head */
789	if (((uint64_t)sizeof(struct log_buffer) + (uint64_t)(pool_buffer->flag).last_pos +
790		pool_item.size) > g_log_pool_size) {
791		pool_buffer->flag.write_loops++;
792		pool_buffer->flag.last_pos = 0;
793	}
794
795	item = (struct log_item *)(uintptr_t)((uint64_t)(uintptr_t)pool_buffer->buffer_start +
796		(uint64_t)pool_buffer->flag.last_pos);
797	if (copy_from_user((void *)item, (void *)pool_item.addr, pool_item.size) != 0) {
798		tloge("item copy_from_user error\n");
799		mutex_unlock(&g_log_pool_lock);
800		return -1;
801	}
802	if (log_pool_item_check(item, pool_item) != 0) {
803		tloge("item check error\n");
804		mutex_unlock(&g_log_pool_lock);
805		return -1;
806	}
807
808	item->serial_no = ++g_logserialno;
809	/* reset g_logserialno */
810	if (item->serial_no == 0)
811		item->serial_no = ++g_logserialno;
812	item->new_line = (unsigned  char)'\n';
813	pool_buffer->flag.reserved[1] = g_logserialno;
814	pool_buffer->flag.last_pos += (uint32_t)pool_item.size;
815	mutex_unlock(&g_log_pool_lock);
816
817	return 0;
818}
819
820static int init_log_pool(void)
821{
822	struct log_buffer *pool_buffer = NULL;
823	uint64_t paddr = get_log_mem_paddr(0);
824
825	g_log_pool_size = get_log_mem_size();
826	if ((UINT64_MAX - paddr) < g_log_pool_size) {
827		tloge("log pool paddr error\n");
828		return -1;
829	}
830	g_log_pool_size /= HALF_DIV_NUM;
831	g_log_pool_va = (uint64_t)(uintptr_t)ioremap_cache(paddr + g_log_pool_size, g_log_pool_size);
832	if (log_pool_check() != 0) {
833		tloge("log pool addr or size error\n");
834		return -1;
835	}
836	pool_buffer = (struct log_buffer *)(uintptr_t)g_log_pool_va;
837
838	/*
839	 * the struct log_buffer magic field use for log retention feature,
840	 * if hit the magic, will retain the old log before reset in log pool,
841	 * or will memset log pool.
842	 */
843	if (pool_buffer->flag.reserved[0] != LOG_ITEM_MAGIC) {
844		(void)memset_s((void *)(uintptr_t)g_log_pool_va, g_log_pool_size, 0, g_log_pool_size);
845		pool_buffer->flag.reserved[0] = LOG_ITEM_MAGIC;
846		pool_buffer->flag.max_len = g_log_pool_size - sizeof(struct log_buffer);
847	} else {
848		g_logserialno = pool_buffer->flag.reserved[1];
849	}
850
851	return 0;
852}
853
854static void free_log_pool(void)
855{
856	if (g_log_pool_va != 0)
857		iounmap((void __iomem *)(uintptr_t)g_log_pool_va);
858	g_log_pool_va = 0;
859	g_log_pool_size = 0;
860	g_logserialno = 0;
861}
862#endif
863
864static long process_tlogger_ioctl(struct file *file,
865	unsigned int cmd, unsigned long arg)
866{
867	struct tlogger_log *log = NULL;
868	long ret = -EINVAL;
869
870	if (!file)
871		return -1;
872
873	log = get_reader_log(file);
874	if (!log) {
875		tloge("log is null\n");
876		return -1;
877	}
878
879	tlogd("logger_ioctl start ++\n");
880	mutex_lock(&log->mutex_info);
881
882	switch (cmd) {
883	case TEELOGGER_GET_VERSION:
884		if (get_teeos_version(cmd, arg) == 0)
885			ret = 0;
886		break;
887	case TEELOGGER_SET_READERPOS_CUR:
888		set_reader_cur_pos(file);
889		ret = 0;
890		break;
891	case TEELOGGER_SET_TLOGCAT_STAT:
892		set_tlogcat_f_stat(file);
893		ret = 0;
894		break;
895	case TEELOGGER_GET_TLOGCAT_STAT:
896		ret = get_tlogcat_f_stat();
897		break;
898#ifdef CONFIG_LOG_POOL
899	case TEELOGGER_GET_LOG_POOL:
900		ret = get_log_pool(arg);
901		break;
902	case TEELOGGER_LOG_POOL_APPEND:
903		ret = log_pool_append(arg);
904		break;
905#endif
906	default:
907		tloge("ioctl error default\n");
908		break;
909	}
910
911	mutex_unlock(&log->mutex_info);
912	return ret;
913}
914
915#ifdef CONFIG_COMPAT
916static long process_tlogger_compat_ioctl(struct file *file,
917	unsigned int cmd, unsigned long arg)
918{
919	tlogd("logger_compat_ioctl ++\n");
920	arg = (unsigned long)(uintptr_t)compat_ptr(arg);
921	return process_tlogger_ioctl(file, cmd, arg);
922}
923#endif
924
925static const struct file_operations g_logger_fops = {
926	.owner = THIS_MODULE,
927	.read = process_tlogger_read,
928	.poll = process_tlogger_poll,
929	.unlocked_ioctl = process_tlogger_ioctl,
930#ifdef CONFIG_COMPAT
931	.compat_ioctl = process_tlogger_compat_ioctl,
932#endif
933	.open = process_tlogger_open,
934	.release = process_tlogger_release,
935};
936
937static int __init register_device(const char *log_name,
938	uintptr_t addr, int size)
939{
940	int ret;
941	struct tlogger_log *log = NULL;
942	unsigned char *buffer = (unsigned char *)addr;
943	(void)size;
944
945	log = kzalloc(sizeof(*log), GFP_KERNEL);
946	if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)log)) {
947		tloge("kzalloc is failed\n");
948		return -ENOMEM;
949	}
950	log->buffer_info = buffer;
951	log->misc_device.minor = MISC_DYNAMIC_MINOR;
952	log->misc_device.name = kstrdup(log_name, GFP_KERNEL);
953	if (!log->misc_device.name) {
954		ret = -ENOMEM;
955		tloge("kstrdup is failed\n");
956		goto out_free_log;
957	}
958	log->misc_device.fops = &g_logger_fops;
959	log->misc_device.parent = NULL;
960
961	init_waitqueue_head(&log->wait_queue_head);
962	INIT_LIST_HEAD(&log->readers);
963	mutex_init(&log->mutex_info);
964	INIT_LIST_HEAD(&log->logs);
965	list_add_tail(&log->logs, &m_log_list);
966
967	/* register misc device for this log */
968	ret = misc_register(&log->misc_device);
969	if (unlikely(ret)) {
970		tloge("failed to register misc device:%s\n",
971			log->misc_device.name);
972		goto out_free_log;
973	}
974	g_log = log;
975	return 0;
976
977out_free_log:
978	if (log->misc_device.name)
979		kfree(log->misc_device.name);
980
981	kfree(log);
982	return ret;
983}
984
985static struct log_item *msg_get_next(unsigned char *buffer_start,
986	uint32_t read_pos, uint32_t scope_len, uint32_t max_len)
987{
988	uint32_t i = 0;
989	struct log_item *item = NULL;
990	uint32_t item_max_size;
991	uint32_t len;
992
993	while (i <= scope_len &&
994		((read_pos + i + sizeof(*item)) < max_len)) {
995		len = (uint32_t)(scope_len - i);
996		item_max_size =
997			((len > LOG_ITEM_MAX_LEN) ? LOG_ITEM_MAX_LEN : len);
998		item = (struct log_item *)(buffer_start + read_pos + i);
999
1000		if (check_log_item_validite(item, item_max_size)) {
1001			if ((read_pos + i + sizeof(*item) +
1002				item->buffer_len) > max_len) {
1003				tloge("check item len error\n");
1004				return NULL;
1005			}
1006
1007			return item;
1008		}
1009
1010		i += LOG_ITEM_LEN_ALIGN;
1011		item = NULL;
1012	}
1013
1014	return NULL;
1015}
1016
1017#ifdef CONFIG_TZDRIVER_MODULE
1018/* there is no way to chown in kernel-5.10 for ko */
1019static int tlogger_chown(const char *file_path, uint32_t file_path_len)
1020{
1021	(void)file_path;
1022	(void)file_path_len;
1023
1024	return 0;
1025}
1026#else
1027static int tlogger_chown(const char *file_path, uint32_t file_path_len)
1028{
1029	(void)file_path_len;
1030	uid_t user = ROOT_UID;
1031	gid_t group = ROOT_GID;
1032	int ret;
1033#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
1034	mm_segment_t old_fs;
1035#endif
1036	get_log_chown(&user, &group);
1037
1038	/* not need modify chown attr */
1039	if (group == ROOT_GID && user == ROOT_UID)
1040		return 0;
1041
1042#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
1043	old_fs = get_fs();
1044	set_fs(KERNEL_DS);
1045#endif
1046#if (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)
1047	ret = (int)ksys_chown((const char __user *)file_path, user, group);
1048#else
1049	ret = (int)sys_chown((const char __user *)file_path, user, group);
1050#endif
1051	if (ret != 0) {
1052		tloge("sys chown for last teemsg file error\n");
1053#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
1054		set_fs(old_fs);
1055#endif
1056		return -1;
1057	}
1058
1059#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
1060	set_fs(old_fs);
1061#endif
1062	return 0;
1063}
1064#endif
1065
1066static int write_version_to_msg(struct file *filep,
1067	loff_t *pos)
1068{
1069	ssize_t write_len;
1070
1071	/* first write tee versino info */
1072	write_len = kernel_write(filep, g_log_buffer->flag.version_info,
1073		strlen(g_log_buffer->flag.version_info), pos);
1074	if (write_len < 0) {
1075		tloge("Failed to write to last teemsg version\n");
1076		return -1;
1077	}
1078
1079	tlogd("Succeed to Write to last teemsg version, len=%zd\n", write_len);
1080	return 0;
1081}
1082
1083static int write_part_log_to_msg(struct file *filep,
1084	unsigned char *buffer, uint32_t buffer_max_len, loff_t *pos,
1085	uint32_t read_off, uint32_t read_off_end)
1086{
1087	struct log_item *next_item = NULL;
1088	uint32_t item_len;
1089	uint32_t total_len = 0;
1090	ssize_t write_len;
1091
1092	next_item = msg_get_next(buffer, read_off,
1093		LOG_ITEM_MAX_LEN, buffer_max_len);
1094
1095	while (next_item && read_off <= read_off_end) {
1096		item_len = next_item->buffer_len + sizeof(*next_item);
1097		write_len = kernel_write(filep, next_item->log_buffer,
1098			next_item->real_len, pos);
1099		if (write_len < 0) {
1100			tloge("Failed to write last teemsg %zd\n", write_len);
1101			return -1;
1102		}
1103
1104		tlogd("Succeed to Write last teemsg, len=%zd\n", write_len);
1105		total_len += item_len;
1106		read_off = (unsigned char *)next_item - buffer + item_len;
1107		if (total_len >= buffer_max_len)
1108			break;
1109
1110		next_item = msg_get_next(buffer, read_off,
1111			LOG_ITEM_MAX_LEN, buffer_max_len);
1112	}
1113
1114	return 0;
1115}
1116
1117static int write_log_to_msg(struct file *filep,
1118	unsigned char *buffer, uint32_t buffer_max_len, loff_t *pos,
1119	uint32_t read_off, uint32_t read_off_end)
1120{
1121	if (read_off < read_off_end) {
1122		return write_part_log_to_msg(filep, buffer, buffer_max_len, pos,
1123			read_off, read_off_end);
1124	} else {
1125		if (write_part_log_to_msg(filep, buffer, buffer_max_len, pos,
1126			read_off, buffer_max_len) != 0)
1127			return -1;
1128		return write_part_log_to_msg(filep, buffer, buffer_max_len, pos,
1129			0, read_off_end);
1130	}
1131}
1132
1133#ifdef CONFIG_TEE_LOG_DUMP_PATH
1134static void update_dumpmsg_offset(uint32_t *read_start, uint32_t *read_end,
1135	uint32_t read_off, uint32_t read_off_end, uint32_t *dump_start_flag, uint32_t *dump_end_flag)
1136{
1137	struct log_item *next_item = NULL;
1138	unsigned char *buffer = g_log_buffer->buffer_start;
1139	uint32_t buffer_max_len = g_log_mem_len - sizeof(*g_log_buffer);
1140	ssize_t item_len;
1141	ssize_t total_len = 0;
1142
1143	next_item = msg_get_next(buffer, read_off,
1144		LOG_ITEM_MAX_LEN, buffer_max_len);
1145
1146	while (next_item && read_off <= read_off_end) {
1147		item_len = next_item->buffer_len + sizeof(*next_item);
1148		if (strstr(next_item->log_buffer, DUMP_START_MAGIC)) {
1149			*read_start = read_off;
1150			*dump_start_flag = 1;
1151		} else if (strstr(next_item->log_buffer, DUMP_END_MAGIC)) {
1152			*read_end = read_off;
1153			*dump_end_flag = 1;
1154		}
1155		read_off = (unsigned char *)next_item - buffer + item_len;
1156		total_len += item_len;
1157		if (total_len >= buffer_max_len)
1158			break;
1159
1160		next_item = msg_get_next(buffer, read_off,
1161			LOG_ITEM_MAX_LEN, buffer_max_len);
1162	}
1163}
1164#endif
1165
1166#ifdef CONFIG_TEE_LOG_DUMP_PATH
1167static int get_dumpmsg_offset(uint32_t *read_start, uint32_t *read_end)
1168{
1169	uint32_t read_off = *read_start;
1170	uint32_t read_off_end = *read_end;
1171	uint32_t buffer_max_len = g_log_mem_len - sizeof(*g_log_buffer);
1172	uint32_t dump_start_flag = 0;
1173	uint32_t dump_end_flag = 0;
1174
1175	if (read_off < read_off_end) {
1176		update_dumpmsg_offset(read_start, read_end, read_off, read_off_end,
1177			&dump_start_flag, &dump_end_flag);
1178	} else {
1179		update_dumpmsg_offset(read_start, read_end, read_off, buffer_max_len,
1180			&dump_start_flag, &dump_end_flag);
1181		update_dumpmsg_offset(read_start, read_end, 0, read_off_end,
1182			&dump_start_flag, &dump_end_flag);
1183	}
1184
1185	if (dump_start_flag == 0 || dump_end_flag == 0) {
1186		tloge("can't find dump start or end\n");
1187		return -1;
1188	} else {
1189		return 0;
1190	}
1191}
1192#endif
1193
1194static int get_msg_buffer(unsigned char **buffer, uint32_t *buffer_max_len,
1195	uint32_t *read_start, uint32_t *read_end,
1196	const char *file_path, uint32_t file_path_len)
1197{
1198	errno_t rc;
1199	int ret;
1200	unsigned char *addr = NULL;
1201	(void)file_path_len;
1202
1203	if (!g_log_buffer)
1204		return -1;
1205
1206	*buffer_max_len = g_log_mem_len - sizeof(*g_log_buffer);
1207
1208	if (*buffer_max_len > LOG_BUFFER_MAX_LEN)
1209		return 0;
1210
1211	*read_start = 0;
1212	*read_end = *buffer_max_len;
1213#ifdef CONFIG_TEE_LOG_DUMP_PATH
1214	if (strcmp(file_path, CONFIG_TEE_LOG_DUMP_PATH) == 0) {
1215		*read_start = g_last_read_offset;
1216		*read_end = ((struct log_buffer*)g_log->buffer_info)->flag.last_pos;
1217		if (get_dumpmsg_offset(read_start, read_end) != 0) {
1218			tloge("get dump offset failed\n");
1219			return -1;
1220		}
1221	}
1222#else
1223	(void)file_path;
1224#endif
1225	addr = kmalloc(*buffer_max_len, GFP_KERNEL);
1226	if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)addr)) {
1227		ret = -ENOMEM;
1228		goto free_res;
1229	}
1230
1231	rc = memcpy_s(addr, *buffer_max_len, g_log_buffer->buffer_start,
1232		*buffer_max_len);
1233	if (rc) {
1234		tloge("memcpy failed %d\n", rc);
1235		ret = -EAGAIN;
1236		goto free_res;
1237	}
1238
1239	*buffer = addr;
1240	return 0;
1241
1242free_res:
1243	if (addr)
1244		kfree(addr);
1245
1246	return ret;
1247}
1248
1249static int open_msg_file(struct file **file,
1250	const char *file_path, uint32_t file_path_len)
1251{
1252	struct file *filep = NULL;
1253	(void)file_path_len;
1254
1255	filep = filp_open(file_path, O_CREAT | O_RDWR | O_TRUNC, OPEN_FILE_MODE);
1256	if (!filep || IS_ERR(filep)) {
1257		tloge("open last teemsg file err %ld\n", PTR_ERR(filep));
1258		return -1;
1259	}
1260
1261	*file = filep;
1262	return 0;
1263}
1264
1265int tlogger_store_msg(const char *file_path, uint32_t file_path_len)
1266{
1267	struct file *filep = NULL;
1268	loff_t pos = 0;
1269	int ret;
1270	uint32_t buffer_max_len = 0;
1271	unsigned char *buffer = NULL;
1272	uint32_t read_start = 0;
1273	uint32_t read_end = 0;
1274
1275	if (!file_path || file_path_len > TEE_LOG_FILE_NAME_MAX) {
1276		tloge("file path is invalid\n");
1277		return -1;
1278	}
1279
1280	if (!g_tlogcat_count) {
1281		tlogd("tlogcat count %u\n", g_tlogcat_count);
1282		return 0;
1283	}
1284
1285	/* copy logs from log memory, then parse the logs */
1286	ret = get_msg_buffer(&buffer, &buffer_max_len,
1287		&read_start, &read_end, file_path, file_path_len);
1288	if (ret != 0)
1289		return ret;
1290
1291	/* exception handling, store trustedcore exception info to file */
1292	ret = open_msg_file(&filep, file_path, file_path_len);
1293	if (ret != 0)
1294		goto free_res;
1295
1296	ret = tlogger_chown(file_path, file_path_len);
1297	if (ret != 0)
1298		goto free_res;
1299
1300	ret = write_version_to_msg(filep, &pos);
1301	if (ret != 0)
1302		goto free_res;
1303
1304	ret = write_log_to_msg(filep, buffer, buffer_max_len,
1305		&pos, read_start, read_end);
1306
1307free_res:
1308	if (buffer) {
1309		kfree(buffer);
1310		buffer = NULL;
1311	}
1312
1313	if (filep != NULL) {
1314		vfs_fsync(filep, 0);
1315		filp_close(filep, 0);
1316	}
1317
1318	/* trigger write teeos log */
1319	tz_log_write();
1320	return ret;
1321}
1322
1323#ifdef DEF_ENG
1324#define KERNEL_IMG_IS_ENG 1
1325#endif
1326int register_mem_to_teeos(uint64_t mem_addr, uint32_t mem_len, bool is_cache_mem)
1327{
1328	struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
1329	struct mb_cmd_pack *mb_pack = NULL;
1330	int ret;
1331
1332	mb_pack = mailbox_alloc_cmd_pack();
1333	if (!mb_pack) {
1334		tloge("mailbox alloc failed\n");
1335		return -ENOMEM;
1336	}
1337
1338	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
1339	smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_LOG_MEM;
1340	mb_pack->operation.paramtypes = teec_param_types(
1341		TEE_PARAM_TYPE_VALUE_INPUT,
1342		TEE_PARAM_TYPE_VALUE_INPUT,
1343		TEE_PARAM_TYPE_VALUE_INPUT,
1344		TEE_PARAM_TYPE_NONE);
1345	mb_pack->operation.params[0].value.a = mem_addr;
1346	mb_pack->operation.params[0].value.b = mem_addr >> ADDR_TRANS_NUM;
1347	mb_pack->operation.params[1].value.a = mem_len;
1348#ifdef DEF_ENG
1349	mb_pack->operation.params[1].value.b = KERNEL_IMG_IS_ENG;
1350#endif
1351	/*
1352	 * is_cache_mem: true, teeos map this memory for cache
1353	 * style; or else map to no cache style
1354	 */
1355	mb_pack->operation.params[2].value.a = is_cache_mem;
1356
1357	smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
1358	smc_cmd.operation_h_phys =
1359		(uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM;
1360
1361	if (is_tee_rebooting())
1362		ret = send_smc_cmd_rebooting(TSP_REQUEST, 0, 0, &smc_cmd);
1363	else
1364		ret = tc_ns_smc(&smc_cmd);
1365
1366	mailbox_free(mb_pack);
1367	if (ret != 0)
1368		tloge("Send log mem info failed\n");
1369
1370	return ret;
1371}
1372
1373static int register_mem_cfg(uint64_t *addr, uint32_t *len)
1374{
1375	int ret;
1376	ret = register_log_mem(addr, len);
1377	if (ret != 0)
1378		tloge("register log mem failed %x\n", ret);
1379
1380	ret = register_log_exception();
1381	if (ret != 0)
1382		tloge("teeos register exception to log module failed\n");
1383
1384	return ret;
1385}
1386
1387static int check_log_mem(uint64_t mem_addr, uint32_t mem_len)
1388{
1389	if (mem_len < TEMP_LOG_MEM_SIZE) {
1390		tloge("log mem init error, too small len:0x%x\n", mem_len);
1391		return -1;
1392	}
1393	if (!mem_addr) {
1394		tloge("mem init failed!!! addr is 0\n");
1395		return -1;
1396	}
1397	return 0;
1398}
1399
1400int register_tloger_mem(void)
1401{
1402	int ret;
1403	uint64_t mem_addr = 0;
1404
1405	ret = register_mem_cfg(&mem_addr, &g_log_mem_len);
1406	if (ret != 0)
1407		return ret;
1408
1409	ret = check_log_mem(mem_addr, g_log_mem_len);
1410	if (ret != 0)
1411		return ret;
1412
1413	g_log_buffer =
1414		(struct log_buffer *)map_log_mem(mem_addr, g_log_mem_len);
1415	if (!g_log_buffer)
1416		return -ENOMEM;
1417
1418	g_log_buffer->flag.max_len = g_log_mem_len - sizeof(*g_log_buffer);
1419
1420	return ret;
1421}
1422
1423static int register_tloger_device(void)
1424{
1425	int ret;
1426
1427	tlogi("tlogcat version 1.0.0\n");
1428	ret = register_device(LOGGER_LOG_TEEOS, (uintptr_t)g_log_buffer,
1429		sizeof(*g_log_buffer) + g_log_buffer->flag.max_len);
1430	if (ret != 0) {
1431		unmap_log_mem((int *)g_log_buffer);
1432		g_log_buffer = NULL;
1433		g_log_mem_len = 0;
1434	}
1435
1436	return ret;
1437}
1438
1439static int register_tloger(void)
1440{
1441	int ret;
1442
1443	ret = register_tloger_mem();
1444	if (ret != 0)
1445		return ret;
1446
1447#ifdef CONFIG_LOG_POOL
1448	ret = init_log_pool();
1449	if (ret != 0)
1450		tloge("init_log_pool init failed\n");
1451#endif
1452
1453	ret = register_tloger_device();
1454
1455	return ret;
1456}
1457
1458static void unregister_mem_cfg(void)
1459{
1460	if (g_log_buffer)
1461		unmap_log_mem((int *)g_log_buffer);
1462
1463	unregister_log_exception();
1464}
1465
1466static void unregister_tlogger(void)
1467{
1468	struct tlogger_log *current_log = NULL;
1469	struct tlogger_log *next_log = NULL;
1470
1471	list_for_each_entry_safe(current_log, next_log, &m_log_list, logs) {
1472		/* we have to delete all the entry inside m_log_list */
1473		misc_deregister(&current_log->misc_device);
1474		kfree(current_log->misc_device.name);
1475		list_del(&current_log->logs);
1476		kfree(current_log);
1477	}
1478
1479#ifdef CONFIG_LOG_POOL
1480	free_log_pool();
1481#endif
1482	unregister_mem_cfg();
1483	g_log_buffer = NULL;
1484	g_log_mem_len = 0;
1485}
1486
1487#ifdef CONFIG_TZDRIVER_MODULE
1488int init_tlogger_service(void)
1489{
1490	return register_tloger();
1491}
1492
1493void free_tlogger_service(void)
1494{
1495	unregister_tlogger();
1496}
1497#else
1498static int __init init_tlogger_service(void)
1499{
1500	return register_tloger();
1501}
1502
1503static void __exit free_tlogger_service(void)
1504{
1505	unregister_tlogger();
1506}
1507#endif
1508
1509#ifdef CONFIG_TZDRIVER
1510device_initcall(init_tlogger_service);
1511module_exit(free_tlogger_service);
1512
1513MODULE_AUTHOR("iTrustee");
1514MODULE_DESCRIPTION("TrustCore Logger");
1515MODULE_VERSION("1.00");
1516#endif
1517