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(¤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 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