• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "tzdebug.h"
33 #include <securec.h>
34 #include <stdarg.h>
35 #include "cmdmonitor.h"
36 #include "mailbox_mempool.h"
37 #include "smc.h"
38 #include "tc_client_sub_driver.h"
39 #include "tc_ns_log.h"
40 #include "teek_client_api.h"
41 #include "teek_client_constants.h"
42 #include "teek_ns_client.h"
43 #include "tzdriver_compat.h"
44 
45 typedef void (*TzdebugOptFunc)(const char *param);
46 
47 struct OptOps {
48     char *name;
49     TzdebugOptFunc func;
50 };
51 
52 static DEFINE_MUTEX(g_meminfoLock);
53 static struct TeeMem g_teeMeminfo = {0};
54 static int SendDumpMem(int flag, const struct TeeMem *statmem);
55 static void TzMemDump(const char *param);
56 
TeeDumpMem(void)57 void TeeDumpMem(void)
58 {
59     TzMemDump(NULL);
60 }
61 
62 /* get meminfo (TeeMem + N * ta_mem < 4Kbyte) from tee */
GetTeeMemInfoCmd(void)63 static int GetTeeMemInfoCmd(void)
64 {
65     int ret;
66     int sret;
67     struct TeeMem *mem = (struct TeeMem *)MailboxAlloc(sizeof(*mem), MB_FLAG_ZERO);
68 
69     if (mem == NULL) {
70         return -1;
71     }
72     ret = SendDumpMem(0, mem);
73     mutex_lock(&g_meminfoLock);
74     sret = memcpy_s((void *)&g_teeMeminfo, sizeof(g_teeMeminfo), mem, sizeof(*mem));
75     if (sret != EOK) {
76         tloge("sret=%d\n", sret);
77     }
78     mutex_unlock(&g_meminfoLock);
79     MailboxFree(mem);
80     return ret;
81 }
82 
83 static atomic_t g_cmdSend = ATOMIC_INIT(1);
84 
SetCmdSendState(void)85 void SetCmdSendState(void)
86 {
87     atomic_set(&g_cmdSend, 1);
88 }
89 
GetTeeMeminfo(struct TeeMem * meminfo)90 int GetTeeMeminfo(struct TeeMem *meminfo)
91 {
92     errno_t ret;
93 
94     if (meminfo == NULL) {
95         return -1;
96     }
97     if (atomic_read(&g_cmdSend)) {
98         if (GetTeeMemInfoCmd() != 0) {
99             return -1;
100         }
101     } else {
102         atomic_set(&g_cmdSend, 0);
103     }
104     mutex_lock(&g_meminfoLock);
105     ret = memcpy_s((void *)meminfo, sizeof(*meminfo),
106         (void *)&g_teeMeminfo, sizeof(g_teeMeminfo));
107     mutex_unlock(&g_meminfoLock);
108     if (ret != EOK) {
109         return -1;
110     }
111 
112     return 0;
113 }
114 EXPORT_SYMBOL(GetTeeMeminfo);
115 
SendDumpMem(int flag,const struct TeeMem * statmem)116 static int SendDumpMem(int flag, const struct TeeMem *statmem)
117 {
118     TcNsSmcCmd smcCmd = { {0}, 0 };
119     struct MbCmdPack *mbPack = NULL;
120     int ret;
121 
122     if (statmem == NULL) {
123         tloge("statmem is NULL\n");
124         return -1;
125     }
126     mbPack = MailboxAllocCmdPack();
127     if (mbPack == NULL) {
128         return -ENOMEM;
129     }
130     smcCmd.cmdId = GLOBAL_CMD_ID_DUMP_MEMINFO;
131     smcCmd.globalCmd = true;
132     mbPack->operation.paramTypes = TEEC_PARAM_TYPES(
133         TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_VALUE_INPUT,
134         TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
135     mbPack->operation.params[TEE_PARAM_ONE].memref.buffer = LOS_PaddrQuery((void *)statmem);
136     mbPack->operation.params[TEE_PARAM_ONE].memref.size = sizeof(*statmem);
137     mbPack->operation.bufferHaddr[TEE_PARAM_ONE] = 0;
138     mbPack->operation.params[TEE_PARAM_TWO].value.a = flag;
139     smcCmd.operationPhys =
140             (unsigned int)LOS_PaddrQuery(&mbPack->operation);
141     smcCmd.operationHphys = 0;
142     ret = TcNsSmc(&smcCmd);
143     if (ret) {
144         tloge("SendDumpMem failed.\n");
145     }
146     MailboxFree(mbPack);
147     return ret;
148 }
149 
ArchiveLog(const char * param)150 static void ArchiveLog(const char *param)
151 {
152     (void)param;
153     TzDebugArchiveLog();
154 }
155 
TzDump(const char * param)156 static void TzDump(const char *param)
157 {
158     (void)param;
159     ShowCmdBitmap();
160     WakeupTcSiq();
161 }
162 
TzMemDump(const char * param)163 static void TzMemDump(const char *param)
164 {
165     struct TeeMem *mem = NULL;
166 
167     (void)param;
168     mem = (struct TeeMem *)MailboxAlloc(sizeof(*mem), MB_FLAG_ZERO);
169     if (mem == NULL) {
170         tloge("mailbox alloc failed\n");
171         return;
172     }
173     if (SendDumpMem(1, mem) != 0) {
174         tloge("send dump mem failed\n");
175     }
176 
177     MailboxFree(mem);
178 }
179 
MemstatThread(UINTPTR arg,int len)180 static int MemstatThread(UINTPTR arg, int len)
181 {
182     (void)len;
183     (void)arg;
184     return 0;
185 }
186 
TzMemStat(const char * param)187 static void TzMemStat(const char *param)
188 {
189     LosTaskCB *stat_tsk = NULL;
190     (void)param;
191     stat_tsk = KthreadRun(MemstatThread, NULL, 0, "tzmemstat");
192     if (IS_ERR(stat_tsk)) {
193         tloge("memstat failed\n");
194     }
195 }
196 
TzLogWriteDbg(const char * param)197 static void TzLogWriteDbg(const char *param)
198 {
199     (void)param;
200 }
201 
202 static void TzHelp(const char *param);
203 
204 static struct OptOps g_optArr[] = {
205     {"help", TzHelp},
206     {"archivelog", ArchiveLog},
207     {"dump", TzDump},
208     {"memdump", TzMemDump},
209     {"logwrite", TzLogWriteDbg},
210     {"dump_service", DumpServicesStatus},
211     {"memstat", TzMemStat},
212 };
213 
TzHelp(const char * param)214 static void TzHelp(const char *param)
215 {
216     uint32_t i;
217     (void)param;
218 
219     for (i = 0; i < sizeof(g_optArr) / sizeof(struct OptOps); i++) {
220         tloge("cmd:%s\n", g_optArr[i].name);
221     }
222 }
223 
TzDbgOptWrite(struct file * filp,const char __user * ubuf,size_t cnt)224 static ssize_t TzDbgOptWrite(struct file *filp,
225     const char __user *ubuf, size_t cnt)
226 {
227     char buf[128] = {0}; /* 128, size of copy from ubuf */
228     char *value = NULL;
229     char *p = NULL;
230     uint32_t i = 0;
231 
232     if ((ubuf == NULL) || (filp == NULL)) {
233         return -EINVAL;
234     }
235 
236     if (cnt >= sizeof(buf)) {
237         return -EINVAL;
238     }
239 
240     if (cnt == 0) {
241         return -EINVAL;
242     }
243 
244     if (copy_from_user(buf, ubuf, cnt)) {
245         return -EFAULT;
246     }
247     buf[cnt] = 0;
248     if (cnt > 0 && buf[cnt - 1] == '\n') {
249         buf[cnt - 1] = 0;
250     }
251     value = buf;
252     p = strsep(&value, ":");
253     if (p == NULL) {
254         return -EINVAL;
255     }
256     for (i = 0; i < sizeof(g_optArr) / sizeof(struct OptOps); i++) {
257         if (!strncmp(p, g_optArr[i].name, strlen(g_optArr[i].name)) &&
258             strlen(p) == strlen(g_optArr[i].name)) {
259             g_optArr[i].func(value);
260             return cnt;
261         }
262     }
263     return -EFAULT;
264 }
265 
266 static const struct file_operations_vfs g_tzDbgOptFops = {
267     .write = TzDbgOptWrite,
268 };
269 
270 #define TC_NS_CLIENT_TZDEBUG "/dev/tzdebug"
271 
TzdebugInit(void)272 int TzdebugInit(void)
273 {
274     int ret = CreateTcClientDevice(TC_NS_CLIENT_TZDEBUG, &g_tzDbgOptFops);
275     if (ret != EOK) {
276         return ret;
277     }
278     return 0;
279 }
280