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
72 struct 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
86 int 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
93 uint32_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 */
99 struct 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 */
127 struct 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
138 struct log_buffer {
139 struct log_buffer_flag flag;
140 unsigned char buffer_start[];
141 };
142
143 static struct log_buffer *g_log_buffer = NULL;
144
145 struct 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
154 static LIST_HEAD(m_log_list);
155
156 struct 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
170 static uint32_t g_log_mem_len = 0;
171 static uint32_t g_tlogcat_count = 0;
172 static struct tlogger_log *g_log;
173
get_reader_log(const struct file * file)174 static 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
check_log_item_validite(const struct log_item * item,uint32_t item_max_size)185 static 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
get_next_log_item(const unsigned char * buffer_start,uint32_t max_len,uint32_t read_pos,uint32_t scope_len,uint32_t * pos)199 static 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
224 struct 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
parse_log_item(char __user * buf,size_t count,struct reader_position * position,uint32_t * read_off,bool * user_buffer_left)231 static 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
get_buffer_info(struct tlogger_reader * reader,struct log_buffer_flag * buffer_flag,struct log_buffer ** log_buffer)276 static 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
get_last_read_pos(struct log_buffer_flag * log_flag,const struct tlogger_reader * reader,uint32_t * log_last_pos,uint32_t * is_read)309 static 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
set_reader_position(struct reader_position * position,const unsigned char * buffer_start,uint32_t max_len,uint32_t start_pos,uint32_t end_pos)341 static 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
proc_read_ret(uint32_t buf_written,const struct tlogger_reader * reader)350 static 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
check_read_params(const struct file * file,const char __user * buf,size_t count)364 static 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 */
trigger_parse_log(char __user * buf,size_t count,uint32_t log_last_pos,struct log_buffer * log_buffer,struct tlogger_reader * reader)382 static 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
process_tlogger_read(struct file * file,char __user * buf,size_t count,loff_t * pos)428 static 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
tz_log_write(void)459 void 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
get_tlogger_log_by_minor(int minor)478 static 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
process_tlogger_open(struct inode * inode,struct file * file)490 static 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
process_tlogger_release(struct inode * ignored,struct file * file)536 static 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
process_tlogger_poll(struct file * file,poll_table * wait)577 static 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
set_reader_cur_pos(const struct file * file)618 static 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
set_tlogcat_f_stat(const struct file * file)641 static 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
get_tlogcat_f_stat(void)659 static int get_tlogcat_f_stat(void)
660 {
661 tlogi("get tlogcat_f-%d\n", g_tlogcat_f);
662 return g_tlogcat_f;
663 }
664
check_user_arg(unsigned long arg,size_t arg_len)665 static 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
get_teeos_version(uint32_t cmd,unsigned long arg)676 static 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
707 static DEFINE_MUTEX(g_log_pool_lock);
708 static uint64_t g_log_pool_va = 0;
709 static uint64_t g_log_pool_size = 0;
710 static uint32_t g_logserialno = 0;
711
get_log_pool(void * argp)712 static 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
log_pool_check(void)733 static 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
log_pool_item_check(struct log_item * item,struct teelogger_log_pool pool_item)750 static 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
log_pool_append(void * argp)761 static 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
init_log_pool(void)820 static 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
free_log_pool(void)854 static 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
process_tlogger_ioctl(struct file * file,unsigned int cmd,unsigned long arg)864 static 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
process_tlogger_compat_ioctl(struct file * file,unsigned int cmd,unsigned long arg)916 static 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
925 static 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
register_device(const char * log_name,uintptr_t addr,int size)937 static 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
977 out_free_log:
978 if (log->misc_device.name)
979 kfree(log->misc_device.name);
980
981 kfree(log);
982 return ret;
983 }
984
msg_get_next(unsigned char * buffer_start,uint32_t read_pos,uint32_t scope_len,uint32_t max_len)985 static 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 */
tlogger_chown(const char * file_path,uint32_t file_path_len)1019 static 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
tlogger_chown(const char * file_path,uint32_t file_path_len)1027 static 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
write_version_to_msg(struct file * filep,loff_t * pos)1066 static 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
write_part_log_to_msg(struct file * filep,unsigned char * buffer,uint32_t buffer_max_len,loff_t * pos,uint32_t read_off,uint32_t read_off_end)1083 static 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
write_log_to_msg(struct file * filep,unsigned char * buffer,uint32_t buffer_max_len,loff_t * pos,uint32_t read_off,uint32_t read_off_end)1117 static 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
update_dumpmsg_offset(uint32_t * read_start,uint32_t * read_end,uint32_t read_off,uint32_t read_off_end,uint32_t * dump_start_flag,uint32_t * dump_end_flag)1134 static 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
get_dumpmsg_offset(uint32_t * read_start,uint32_t * read_end)1167 static 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
get_msg_buffer(unsigned char ** buffer,uint32_t * buffer_max_len,uint32_t * read_start,uint32_t * read_end,const char * file_path,uint32_t file_path_len)1194 static 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
1242 free_res:
1243 if (addr)
1244 kfree(addr);
1245
1246 return ret;
1247 }
1248
open_msg_file(struct file ** file,const char * file_path,uint32_t file_path_len)1249 static 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
tlogger_store_msg(const char * file_path,uint32_t file_path_len)1265 int 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
1307 free_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
register_mem_to_teeos(uint64_t mem_addr,uint32_t mem_len,bool is_cache_mem)1326 int 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
register_mem_cfg(uint64_t * addr,uint32_t * len)1373 static 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
check_log_mem(uint64_t mem_addr,uint32_t mem_len)1387 static 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
register_tloger_mem(void)1400 int 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
register_tloger_device(void)1423 static 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
register_tloger(void)1439 static 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
unregister_mem_cfg(void)1458 static 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
unregister_tlogger(void)1466 static 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(¤t_log->misc_device);
1474 kfree(current_log->misc_device.name);
1475 list_del(¤t_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
init_tlogger_service(void)1488 int init_tlogger_service(void)
1489 {
1490 return register_tloger();
1491 }
1492
free_tlogger_service(void)1493 void free_tlogger_service(void)
1494 {
1495 unregister_tlogger();
1496 }
1497 #else
init_tlogger_service(void)1498 static int __init init_tlogger_service(void)
1499 {
1500 return register_tloger();
1501 }
1502
free_tlogger_service(void)1503 static void __exit free_tlogger_service(void)
1504 {
1505 unregister_tlogger();
1506 }
1507 #endif
1508
1509 #ifdef CONFIG_TZDRIVER
1510 device_initcall(init_tlogger_service);
1511 module_exit(free_tlogger_service);
1512
1513 MODULE_AUTHOR("iTrustee");
1514 MODULE_DESCRIPTION("TrustCore Logger");
1515 MODULE_VERSION("1.00");
1516 #endif
1517