diff --git a/trustzone-awared-vm/deployment.md b/trustzone-awared-vm/deployment.md
new file mode 100644
index 0000000000000000000000000000000000000000..7118fc6ef8df64946bd0d1903aa77cf7c60f5757
--- /dev/null
+++ b/trustzone-awared-vm/deployment.md
@@ -0,0 +1,266 @@
+## Host
+
+**步骤1**.获取vtzb_proxy源码
+
+**步骤2** 获取itrustee_tzdriver源码。
+
+下载地址:**https://gitee.com/openeuler/itrustee_tzdriver**
+
+代码分支:master
+
+**步骤3**. 获取libboundscheck源码。
+
+* 下载地址:**https://gitee.com/openeuler/libboundscheck**
+
+* 代码分支:master
+
+**步骤4**.
+
+将下载、解压缩后libboundscheck源码放置在“vtzb_proxy/”目录与“itrustee_tzdriver”目录下,并修改文件夹名称为libboundscheck
+
+**步骤5**. 编译vtzb_proxy
+
+```
+cd vtzb_proxy && make
+```
+
+**步骤6**.Patch Application
+
+进入目标目录 itrustee_tzdriver的父级目录,确保补丁文件和目标目录在同一级目录下
+
+```
+cd itrustee_tzdriver
+patch -p1 <../tzdriver.patch
+
+```
+
+**步骤7**.编译itrustee_tzdriver
+
+```
+cd itrustee_tzdriver && make
+```
+
+**步骤8**.加载tzdriver.ko
+
+```
+sudo insmod tzdriver.ko
+```
+
+
+
+## QEMU
+
+**步骤1**.获取qemuv5.0.0源码
+
+```
+git clone -b v5.0.0 https://git.qemu.org/git/qemu.git
+```
+
+**步骤2**.Patch Application
+
+进入目标目录 `qemu` 的父级目录,确保补丁文件和目标目录在同一级目录下
+
+```
+cd qemu
+patch -p1 <../qemu.patch
+```
+
+**步骤3**.编译qemu
+
+```
+cd qemu
+mkdir build
+cd build
+../configure --target-list=aarch64-softmmu
+make -j$(nproc)
+
+```
+
+**步骤4**.修改虚拟机vm.xml配置文件
+
+```
+
+ openEulerVM03
+ 8
+ 4
+
+ hvm
+ /usr/share/edk2/aarch64/QEMU_EFI-pflash.raw
+ /var/lib/libvirt/qemu/nvram/openEulerVM.fd
+
+
+
+
+
+
+
+
+ 1
+
+ destroy
+ restart
+ restart
+
+ /home/vmuser/tools/qemu/build/aarch64-softmmu/qemu-system-aarch64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+定义5个虚拟串口,socket的path、虚拟串口的name字段与上面保持一致。
+
+host里socket路径""/tmp/vm_vtzb_sock[0-4]"
+
+VM 里虚拟串口路径"/dev/virtio-ports/vtzf_serialport[0-4]"
+
+
+
+**步骤5**.定义并启动虚拟机
+
+```
+virsh define vm.xml
+virsh start openEulerVM03
+```
+
+
+
+## VM
+
+##### 步骤1. 获取itrustee_client源码。
+
+* 下载地址:**https://gitee.com/openeuler/itrustee_client**
+
+* 代码分支:master
+
+##### 步骤2. 获取vtzdriver源码。
+
+##### 步骤3. 获取libboundscheck源码。
+
+* 下载地址:**https://gitee.com/openeuler/libboundscheck**
+
+* 代码分支:master
+
+##### 步骤4.
+
+将下载、解压缩后libboundscheck源码放置在“itrustee_client/”目录以及“vtzdriver”目录下,并修改文件夹名称为libboundscheck
+
+##### 步骤5. 修改itrustee_client目录下的Makefile
+
+```
+ 82 #APP_CFLAGS += -DCONFIG_KUNPENG_PLATFORM -DCONFIG_AUTH_USERNAME -DCONFIG_AGENT_FS -DCONFIG_AGENT_MISC -DCONFIG_AGENT_SECLOAD
+ 83 APP_CFLAGS += -DCONFIG_KUNPENG_PLATFORM -DCONFIG_AUTH_USERNAME
+
+```
+
+* 去除teecd宏定义 -DCONFIG_AGENT_FS -DCONFIG_AGENT_MISC -DCONFIG_AGENT_SECLOAD。(agent及其相关功能还未实现)
+
+##### 步骤6. 编译itrustee_client。
+
+```
+cd itrustee_client && make
+```
+
+##### 步骤7. 部署itrustee_client。
+
+```
+cp -rf dist/\*.so /usr/lib64 && ldconfig
+cp -rf dist/teecd /usr/bin
+cp -rf dist/tlogcat /usr/bin
+\# 可选
+cp -rf dist/tee_teleport /usr/bin
+cp -rf dist/agentd /usr/bin
+```
+
+##### 步骤8. 编译vtzdriver
+
+```
+cd vtzdriver && make
+```
+
+##### 步骤9.加载 vtzfdriver.ko
+
+```
+sudo insmod vtzfdriver.ko
+```
+
+
+
+## RUN
+
+VM上的agent功能还未实现,物理机重启后重新加载驱动,host需保持运行teecd加载kunpeng_sec_drv.sec。
+
+host:
+
+```
+sudo /usr/bin/teecd
+sudo ./vtzb_proxy
+```
+
+若host与VM通道正常,会打印信息
+
+```
+open new socket
+open new socket
+```
+
+VM:
+
+```
+sudo /usr/bin/teecd
+```
+
+```
+sudo /vendor/bin/testcase1 [1-9]
+```
+
diff --git a/trustzone-awared-vm/host/qemu.patch b/trustzone-awared-vm/host/qemu.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c1f56caa66ca8aed53e02a5a3c48781913917f1d
--- /dev/null
+++ b/trustzone-awared-vm/host/qemu.patch
@@ -0,0 +1,940 @@
+diff -Naur '--exclude=.git' ./qemu/hw/char/tc_ns_client.h ./qemu_after/hw/char/tc_ns_client.h
+--- ./qemu/hw/char/tc_ns_client.h 1970-01-01 08:00:00.000000000 +0800
++++ ./qemu_after/hw/char/tc_ns_client.h 2023-08-01 15:09:17.724000000 +0800
+@@ -0,0 +1,162 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
++ * Licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ */
++
++#ifndef _TC_NS_CLIENT_H_
++#define _TC_NS_CLIENT_H_
++#include "tee_client_type.h"
++#define TC_DEBUG
++
++#define INVALID_TYPE 0x00
++#define TEECD_CONNECT 0x01
++#ifndef ZERO_SIZE_PTR
++#define ZERO_SIZE_PTR ((void *)16)
++#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR)
++#endif
++
++#define UUID_SIZE 16
++
++#define TC_NS_CLIENT_IOC_MAGIC 't'
++#define TC_NS_CLIENT_DEV "tc_ns_client"
++#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client"
++#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private"
++#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm"
++
++enum ConnectCmd {
++ GET_FD,
++ GET_TEEVERSION,
++ SET_SYS_XML,
++ GET_TEECD_VERSION,
++};
++
++typedef struct {
++ unsigned int method;
++ unsigned int mdata;
++} TC_NS_ClientLogin;
++
++typedef union {
++ struct {
++ unsigned long long buffer;
++ unsigned long long offset;
++ unsigned long long size_addr;
++ } memref;
++ struct {
++ unsigned long long a_addr;
++ unsigned long long b_addr;
++ } value;
++} TC_NS_ClientParam;
++
++typedef struct {
++ unsigned int code;
++ unsigned int origin;
++} TC_NS_ClientReturn;
++
++typedef struct {
++ unsigned char uuid[UUID_SIZE];
++ unsigned int session_id;
++ unsigned int cmd_id;
++ TC_NS_ClientReturn returns;
++ TC_NS_ClientLogin login;
++ TC_NS_ClientParam params[TEEC_PARAM_NUM];
++ unsigned int paramTypes;
++ bool started;
++ unsigned int callingPid;
++ unsigned int file_size;
++ union {
++ char *file_buffer;
++ struct {
++ uint32_t file_addr;
++ uint32_t file_h_addr;
++ } memref;
++ };
++} TC_NS_ClientContext;
++
++typedef struct {
++ uint32_t seconds;
++ uint32_t millis;
++} TC_NS_Time;
++
++typedef struct {
++ uint16_t tzdriver_version_major;
++ uint16_t tzdriver_version_minor;
++ uint32_t reserved[15];
++} TC_NS_TEE_Info;
++
++enum SecFileType {
++ LOAD_TA = 0,
++ LOAD_SERVICE,
++ LOAD_LIB,
++ LOAD_DYNAMIC_DRV,
++ LOAD_PATCH,
++ LOAD_TYPE_MAX
++};
++
++struct SecFileInfo {
++ enum SecFileType fileType;
++ uint32_t fileSize;
++ int32_t secLoadErr;
++};
++
++struct SecLoadIoctlStruct {
++ struct SecFileInfo secFileInfo;
++ TEEC_UUID uuid;
++ union {
++ char *fileBuffer;
++ struct {
++ uint32_t file_addr;
++ uint32_t file_h_addr;
++ } memref;
++ };
++}__attribute__((packed));
++
++struct AgentIoctlArgs {
++ uint32_t id;
++ uint32_t bufferSize;
++ union {
++ void *buffer;
++ unsigned long long addr;
++ };
++};
++
++#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext)
++#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext)
++#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext)
++#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int)
++#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int)
++#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int)
++#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs)
++#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int)
++#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct)
++#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext)
++#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int)
++#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext)
++#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int)
++#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int)
++#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int)
++#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time)
++#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int)
++#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int)
++#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int)
++#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int)
++#ifdef CONFIG_CMS_SIGNATURE
++#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl)
++#endif
++#ifdef CONFIG_TEE_TELEPORT_SUPPORT
++#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs)
++#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs)
++#endif
++#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info)
++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int)
++
++TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation);
++#endif
++
++
+diff -Naur '--exclude=.git' ./qemu/hw/char/tee_client_constants.h ./qemu_after/hw/char/tee_client_constants.h
+--- ./qemu/hw/char/tee_client_constants.h 1970-01-01 08:00:00.000000000 +0800
++++ ./qemu_after/hw/char/tee_client_constants.h 2023-08-09 15:39:42.324000000 +0800
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved.
++ * Licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ */
++
++#ifndef _TEE_CLIENT_CONSTANTS_H_
++#define _TEE_CLIENT_CONSTANTS_H_
++
++enum TEEC_ReturnCode {
++ TEEC_SUCCESS = 0x0, /* success */
++ TEEC_ERROR_INVALID_CMD, /* invalid command */
++ TEEC_ERROR_SERVICE_NOT_EXIST, /* target service is not exist */
++ TEEC_ERROR_SESSION_NOT_EXIST, /* session between client and service is not exist */
++ TEEC_ERROR_SESSION_MAXIMUM, /* exceed max num of sessions */
++ TEEC_ERROR_REGISTER_EXIST_SERVICE, /* cannot register the service which already exist */
++ TEEC_ERROR_TAGET_DEAD_FATAL, /* system error occurs in TEE */
++ TEEC_ERROR_READ_DATA, /* failed to read data in file */
++ TEEC_ERROR_WRITE_DATA, /* failed to write data to file */
++ TEEC_ERROR_TRUNCATE_OBJECT, /* data is truncated */
++ TEEC_ERROR_SEEK_DATA, /* failed to seek data in file */
++ TEEC_ERROR_FSYNC_DATA, /* failed to sync data in file */
++ TEEC_ERROR_RENAME_OBJECT, /* failed to rename file */
++ TEEC_ERROR_TRUSTED_APP_LOAD_ERROR, /* failed to load Trusted Application */
++ TEEC_ERROR_GENERIC = 0xFFFF0000, /* generic error occurs */
++ TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001, /* permission check failed, in initilize context or
++ open session or invoke commnad */
++ TEEC_ERROR_CANCEL = 0xFFFF0002, /* operation is already canceled */
++ TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003, /* confilct occurs in concurrent access to data,
++ error occurs in file operaions generally */
++ TEEC_ERROR_EXCESS_DATA = 0xFFFF0004, /* exceed max data to be handled by system */
++ TEEC_ERROR_BAD_FORMAT = 0xFFFF0005, /* data format is invalid, Trusted Application cannot
++ handle it */
++ TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006, /* invalid parameters */
++ TEEC_ERROR_BAD_STATE = 0xFFFF0007, /* operation failed in current state, when try to access
++ storage without initilize storage service */
++ TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008, /* cannot find target item */
++ TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009, /* request operation is not implemented */
++ TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A, /* request operation is not supported */
++ TEEC_ERROR_NO_DATA = 0xFFFF000B, /* no data present for current operation */
++ TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C, /* system resource if out of use */
++ TEEC_ERROR_BUSY = 0xFFFF000D, /* system is too busy to handle current operation */
++ TEEC_ERROR_COMMUNICATION = 0xFFFF000E, /* error occurs when client try to communicate
++ with Trusted Application */
++ TEEC_ERROR_SECURITY = 0xFFFF000F, /* security error occurs */
++ TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010, /* out buffer is not enough for current request */
++ TEEC_ERROR_MAC_INVALID = 0xFFFF3071, /* MAC value check failed */
++ TEEC_ERROR_TARGET_DEAD = 0xFFFF3024, /* Trusted Application is crashed */
++ TEEC_FAIL = 0xFFFF5002, /* common error */
++ TEEC_ERROR_EXTERNAL_CANCEL = 0xFFFF0011, /* used by adapt only, event caused User Interface operation aborted */
++ TEEC_ERROR_OVERFLOW = 0xFFFF300F, /* used by adapt only */
++ TEEC_ERROR_STORAGE_NO_SPACE = 0xFFFF3041, /* used by adapt only */
++ TEEC_ERROR_SIGNATURE_INVALID = 0xFFFF3072, /* used by adapt only */
++ TEEC_ERROR_TIME_NOT_SET = 0xFFFF5000, /* used by adapt only */
++ TEEC_ERROR_TIME_NEEDS_RESET = 0xFFFF5001, /* used by adapt only */
++ TEEC_ERROR_IPC_OVERFLOW = 0xFFFF9114 /* ipc overflow */
++};
++
++enum TEEC_ReturnCodeOrigin {
++ TEEC_ORIGIN_API = 0x1, /* error occurs in handling client API */
++ TEEC_ORIGIN_COMMS = 0x2, /* error occurs in communicating between REE and TEE */
++ TEEC_ORIGIN_TEE = 0x3, /* error occurs in TEE */
++ TEEC_ORIGIN_TRUSTED_APP = 0x4, /* error occurs in Trusted Application */
++};
++
++enum TEEC_SharedMemCtl {
++ TEEC_MEM_INPUT = 0x1, /* input type of memroy */
++ TEEC_MEM_OUTPUT = 0x2, /* output type of memory */
++ TEEC_MEM_INOUT = 0x3, /* memory is used as both input and output */
++ TEEC_MEM_SHARED_INOUT = 0x4, /* no copy shared memory */
++};
++
++enum TEEC_ParamType {
++ TEEC_NONE = 0x0, /* unused parameter */
++ TEEC_VALUE_INPUT = 0x01, /* input type of value, refer TEEC_Value */
++ TEEC_VALUE_OUTPUT = 0x02, /* output type of value, refer TEEC_Value */
++ TEEC_VALUE_INOUT = 0x03, /* value is used as both input and output, refer TEEC_Value */
++ TEEC_MEMREF_TEMP_INPUT = 0x05, /* input type of temp memory reference, refer TEEC_TempMemoryReference */
++ TEEC_MEMREF_TEMP_OUTPUT = 0x06, /* output type of temp memory reference, refer TEEC_TempMemoryReference */
++ TEEC_MEMREF_TEMP_INOUT = 0x07, /* temp memory reference used as both input and output,
++ refer TEEC_TempMemoryReference */
++ TEEC_ION_INPUT = 0x08, /* input type of icon memory reference, refer TEEC_IonReference */
++ TEEC_ION_SGLIST_INPUT = 0x09, /* input type of ion memory block reference, refer TEEC_IonSglistReference */
++ TEEC_MEMREF_SHARED_INOUT = 0x0a, /* no copy mem */
++ TEEC_MEMREF_WHOLE = 0xc, /* use whole memory block, refer TEEC_RegisteredMemoryReference */
++ TEEC_MEMREF_PARTIAL_INPUT = 0xd, /* input type of memory reference, refer TEEC_RegisteredMemoryReference */
++ TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, /* output type of memory reference, refer TEEC_RegisteredMemoryReference */
++ TEEC_MEMREF_PARTIAL_INOUT = 0xf /* memory reference used as both input and output,
++ refer TEEC_RegisteredMemoryReference */
++};
++
++/****************************************************
++ * Session Login Methods
++ ****************************************************/
++enum TEEC_LoginMethod {
++ TEEC_LOGIN_PUBLIC = 0x0, /* no Login data is provided */
++ TEEC_LOGIN_USER, /* Login data about the user running the
++ Client Application process is provided */
++ TEEC_LOGIN_GROUP, /* Login data about the group running
++ the Client Application process is provided */
++ TEEC_LOGIN_APPLICATION = 0x4, /* Login data about the running Client
++ Application itself is provided */
++ TEEC_LOGIN_USER_APPLICATION = 0x5, /* Login data about the user running the
++ Client Application and about the
++ Client Application itself is provided */
++ TEEC_LOGIN_GROUP_APPLICATION = 0x6, /* Login data about the group running
++ the Client Application and about the
++ Client Application itself is provided */
++ TEEC_LOGIN_IDENTIFY = 0x7, /* Login data is provided by REE system */
++};
++enum TST_CMD_ID {
++ TST_CMD_ID_01 = 1,
++ TST_CMD_ID_02,
++ TST_CMD_ID_03,
++ TST_CMD_ID_04,
++ TST_CMD_ID_05
++};
++
++#define TEEC_PARAM_NUM 4 /* teec param max number */
++#endif
+diff -Naur '--exclude=.git' ./qemu/hw/char/tee_client_list.h ./qemu_after/hw/char/tee_client_list.h
+--- ./qemu/hw/char/tee_client_list.h 1970-01-01 08:00:00.000000000 +0800
++++ ./qemu_after/hw/char/tee_client_list.h 2023-08-01 14:18:18.616000000 +0800
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved.
++ * iTrustee licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ */
++
++#ifndef TEE_CLIENT_LIST_H
++#define TEE_CLIENT_LIST_H
++
++struct ListNode {
++ struct ListNode *next; /* point to next node */
++ struct ListNode *prev; /* point to prev node */
++};
++
++#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member))
++#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member))
++
++#define LIST_DECLARE(name) \
++ struct ListNode name = { \
++ .next = &name, \
++ .prev = &name, \
++ }
++
++static inline void ListInit(struct ListNode *list)
++{
++ list->next = list;
++ list->prev = list;
++}
++
++#define LIST_HEAD(list) ((list)->next)
++#define LIST_TAIL(list) ((list)->prev)
++#define LIST_EMPTY(list) ((list) == (list)->next)
++
++static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry)
++{
++ list->next->prev = entry;
++ entry->next = list->next;
++ entry->prev = list;
++ list->next = entry;
++}
++
++static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry)
++{
++ entry->next = list;
++ entry->prev = list->prev;
++ list->prev->next = entry;
++ list->prev = entry;
++}
++
++static inline void ListRemoveEntry(struct ListNode *entry)
++{
++ entry->prev->next = entry->next;
++ entry->next->prev = entry->prev;
++}
++
++static inline struct ListNode *ListRemoveHead(struct ListNode *list)
++{
++ struct ListNode *entry = NULL;
++ if (!LIST_EMPTY(list)) {
++ entry = list->next;
++ ListRemoveEntry(entry);
++ }
++ return entry;
++}
++
++static inline struct ListNode *ListRemoveTail(struct ListNode *list)
++{
++ struct ListNode *entry = NULL;
++ if (!LIST_EMPTY(list)) {
++ entry = list->prev;
++ ListRemoveEntry(entry);
++ }
++ return entry;
++}
++
++#define LIST_ENTRY(ptr, type, member) \
++ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
++
++#define LIST_FOR_EACH(pos, list) \
++ for (pos = (list)->next; pos != (list); pos = pos->next)
++
++#define LIST_FOR_EACH_SAFE(pos, n, list) \
++ for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next)
++
++#define LIST_FOR_EACH_ENTRY(pos, list, member) \
++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \
++ pos = LIST_ENTRY(pos->member.next, typeof(*pos), member))
++
++#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \
++ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \
++ member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member))
++
++#endif
++
++
+diff -Naur '--exclude=.git' ./qemu/hw/char/tee_client_type.h ./qemu_after/hw/char/tee_client_type.h
+--- ./qemu/hw/char/tee_client_type.h 1970-01-01 08:00:00.000000000 +0800
++++ ./qemu_after/hw/char/tee_client_type.h 2023-08-01 14:32:33.296000000 +0800
+@@ -0,0 +1,134 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved.
++ * Licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ */
++
++#ifndef _TEE_CLIENT_TYPE_H_
++#define _TEE_CLIENT_TYPE_H_
++
++#include
++#include
++#include
++#include
++#include
++#include "tee_client_list.h"
++#include "tee_client_constants.h"
++
++typedef enum TEEC_ReturnCode TEEC_Result;
++
++typedef struct {
++ uint32_t timeLow;
++ uint16_t timeMid;
++ uint16_t timeHiAndVersion;
++ uint8_t clockSeqAndNode[8];
++} TEEC_UUID;
++
++typedef struct {
++ int32_t fd;
++ uint8_t *ta_path;
++ struct ListNode session_list;
++ struct ListNode shrd_mem_list;
++ union {
++ struct {
++ void *buffer;
++ sem_t buffer_barrier;
++ } share_buffer;
++ uint64_t imp; /* for adapt */
++ };
++} TEEC_Context;
++
++typedef struct {
++ uint32_t session_id;
++ TEEC_UUID service_id;
++ uint32_t ops_cnt;
++ union {
++ struct ListNode head;
++ uint64_t imp; /* for adapt */
++ };
++ TEEC_Context *context;
++} TEEC_Session;
++
++typedef struct {
++ void *buffer;
++ uint32_t size;
++ uint32_t flags; /* reference to TEEC_SharedMemCtl */
++ uint32_t ops_cnt;
++ bool is_allocated; /* identify whether the memory is registered or allocated */
++ union {
++ struct ListNode head;
++ void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */
++ };
++ TEEC_Context *context;
++} TEEC_SharedMemory;
++
++/*
++ * the corresponding param types are
++ * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT
++ */
++typedef struct {
++ void *buffer;
++ uint32_t size;
++} TEEC_TempMemoryReference;
++
++/*
++ * the corresponding param types are
++ * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT
++ * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT
++ */
++typedef struct {
++ TEEC_SharedMemory *parent;
++ uint32_t size;
++ uint32_t offset;
++} TEEC_RegisteredMemoryReference;
++
++/*
++ * the corresponding param types are
++ * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT
++ */
++typedef struct {
++ uint32_t a;
++ uint32_t b;
++} TEEC_Value;
++
++typedef struct {
++ int ion_share_fd;
++ uint32_t ion_size;
++} TEEC_IonReference;
++
++typedef union {
++ TEEC_TempMemoryReference tmpref;
++ TEEC_RegisteredMemoryReference memref;
++ TEEC_Value value;
++ TEEC_IonReference ionref;
++} TEEC_Parameter;
++
++typedef struct {
++ uint32_t event_type; /* Tui event type */
++ uint32_t value; /* return value, is keycode if tui event is getKeycode */
++ uint32_t notch; /* notch size of the screen for tui */
++ uint32_t width; /* width of foldable screen */
++ uint32_t height; /* height of foldable screen */
++ uint32_t fold_state; /* state of foldable screen */
++ uint32_t display_state; /* one state of folded state */
++ uint32_t phy_width; /* real width of the mobile */
++ uint32_t phy_height; /* real height of the mobile */
++} TEEC_TUI_Parameter;
++
++typedef struct {
++ uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */
++ uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */
++ TEEC_Parameter params[TEEC_PARAM_NUM];
++ TEEC_Session *session;
++ bool cancel_flag;
++} TEEC_Operation;
++
++#endif
++
++
+diff -Naur '--exclude=.git' ./qemu/hw/char/virtio-console.c ./qemu_after/hw/char/virtio-console.c
+--- ./qemu/hw/char/virtio-console.c 2023-08-01 14:07:32.320000000 +0800
++++ ./qemu_after/hw/char/virtio-console.c 2023-08-03 17:27:07.592000000 +0800
+@@ -20,6 +20,14 @@
+ #include "qapi/error.h"
+ #include "qapi/qapi-events-char.h"
+
++#include "qom/object.h"
++#include "hw/core/cpu.h"
++#include "sysemu/hw_accel.h"
++#include "monitor/monitor.h"
++#include
++#include
++#include "tc_ns_client.h"
++
+ #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport"
+ #define VIRTIO_CONSOLE(obj) \
+ OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT)
+@@ -45,6 +53,115 @@
+ return FALSE;
+ }
+
++
++#define DEBUG 1
++
++#ifdef DEBUG
++static void debug(const char *fmt, ...)
++{
++ va_list args;
++
++ va_start(args, fmt);
++ vfprintf(stderr, fmt, args);
++ va_end(args);
++}
++
++#define PRINTF_SIZE 16
++static void dump_buff(const char *buffer, size_t bufLen)
++{
++ size_t i;
++ if (buffer == NULL || bufLen == 0) {
++ return;
++ }
++
++ // printf("\n--------------------------------------------------\n");
++ printf("--------------------------------------------------\n");
++ printf("bufLen = %d\n", (int)bufLen);
++ for (i = 0; i < bufLen; i++) {
++ if (i % PRINTF_SIZE == 0 && i != 0) {
++ printf("\n");
++ }
++ printf("%02x ", *(buffer + i));
++ }
++ printf("\n--------------------------------------------------\n");
++ return;
++}
++#else
++#define debug(fmt, ...) do { } while (0)
++
++#define dump_buff(buffer, bufLen) do { } while (0)
++#endif
++
++#define VTZF_OPEN_TZD 15
++#define VTZF_OPEN_SESSION 31
++#define VTZF_SEND_CMD 33
++#define VTZF_FS_REGISTER_AGENT 45
++#define VTZF_LOAD_SEC 53
++
++#define TEEC_PARAM_NUM 4 /* teec param max number */
++
++#define IS_TEMP_MEM(paramType) \
++ (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \
++ ((paramType) == TEEC_MEMREF_TEMP_INOUT))
++
++#define IS_PARTIAL_MEM(paramType) \
++ (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \
++ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT))
++
++#define IS_VALUE_MEM(paramType) \
++ (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT))
++
++#define TEEC_PARAM_TYPE_GET(paramTypes, index) \
++ (((paramTypes) >> (4*(index))) & 0x0F)
++
++typedef struct {
++ uint32_t cmd; // 4, 4 bytes
++ uint32_t seq_num; // second
++ uint32_t vmid;
++ uint32_t flag;
++} struct_packet_cmd_open_tzd;
++
++typedef struct {
++ uint32_t cmd;
++ uint32_t seq_num;
++ __s32 ptzfd;
++ void *addr;
++ struct AgentIoctlArgs args;
++} struct_packet_cmd_regagent;
++
++typedef struct {
++ uint32_t cmd;
++ uint32_t seq_num;
++ __s32 ptzfd;
++ __s32 cpu_index;
++ struct SecLoadIoctlStruct ioctlArg;
++} struct_packet_cmd_load_sec;
++
++typedef struct {
++ uint32_t cmd;
++ uint32_t seq_num;
++ int32_t ptzfd;
++ int32_t cpu_index;
++ TC_NS_ClientContext cliContext;
++} struct_packet_cmd_session;
++
++typedef struct {
++ uint32_t cmd; // 4, 4 bytes
++ int32_t ptzfd; // 4, 8 bytes
++ int32_t cpu_index; // 4, 12 bytes
++ unsigned long long addrs[TEEC_PARAM_NUM];
++ TC_NS_ClientContext cliContext;
++} struct_vtzf_packet_cmd_send_cmd;
++
++typedef struct {
++ uint32_t cmd; // 4, 4 bytes
++ __s32 ptzfd; // 4, 8 bytes
++ uint64_t buffer; // 8, 16 bytes
++ uint32_t size; // 4, 20 bytes
++ uint32_t offset; // 4, 24 bytes
++}struct_vtzf_packet_cmd_mmap;
++
++
+ /* Callback function that's called when the guest sends us data */
+ static ssize_t flush_buf(VirtIOSerialPort *port,
+ const uint8_t *buf, ssize_t len)
+@@ -57,7 +174,223 @@
+ return len;
+ }
+
+- ret = qemu_chr_fe_write(&vcon->chr, buf, len);
++ uint8_t buf01[90 * 1024];
++ memcpy(buf01, buf, len);
++
++ debug("\n");
++ debug("debug, %s, %s, %d \n", __FILE__, __func__, __LINE__);
++ debug(" virtio-console virtserialport name = %s, id = %d \n", port->name, (int)port->id);
++ debug(" have_data flush_buf, buflen = %d \n", len);
++ // dump_buff((char *)buf, len);
++ dump_buff((char *)buf, 0);
++
++ if ( len >= 4 ) {
++ uint32_t ui32_cmd;
++ ui32_cmd = 0;
++ //struct_vtzf_packet_cmd *vtzf_packet_cmd;
++
++ uint32_t ui32_tmp;
++ int i;
++ for (i = 0; i < 4; i++)
++ {
++ ui32_tmp = buf[i];
++ ui32_tmp = ui32_tmp << (i * 8);
++ ui32_cmd = ui32_cmd | ui32_tmp;
++ }
++
++ switch( ui32_cmd ) {
++ case VTZF_OPEN_TZD:
++ debug(" command is VTZF_OPEN_TZD \n");
++ if ( len >= sizeof(struct_packet_cmd_open_tzd)) {
++ struct_packet_cmd_open_tzd* vtzf_packet_cmd = (struct_packet_cmd_open_tzd *)buf01;
++ pid_t qemu_pid = getpid();
++ debug(" qemu_pid = 0x%016lx, %d \n",qemu_pid, qemu_pid);
++ vtzf_packet_cmd->vmid = qemu_pid;
++ }
++ break;
++ case VTZF_LOAD_SEC:
++ debug(" command is VTZF_LOAD_SEC \n");
++ if (len >= sizeof(struct_packet_cmd_load_sec)) {
++ struct_packet_cmd_load_sec* vtzf_packet_cmd = (struct_packet_cmd_load_sec *)buf01;
++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->ioctlArg.fileBuffer);
++
++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->ioctlArg.fileBuffer;
++ Error *local_err = NULL;
++ MemoryRegion *mr = NULL;
++ void *ptr_hva;
++
++ ptr_hva = gpa2hva(&mr, gpa, &local_err);
++ if (local_err) {
++ debug(" gpa2hva failed \n");
++ } else {
++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++
++ memory_region_unref(mr);
++
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->ioctlArg.fileBuffer = (void *)ui64_hva;
++ }
++ }
++ break;
++ case VTZF_FS_REGISTER_AGENT:
++ debug(" command is VTZF_FS_REGISTER_AGENT \n");
++ if (len >= sizeof(struct_packet_cmd_regagent)) {
++ struct_packet_cmd_regagent* vtzf_packet_cmd = (struct_packet_cmd_regagent *)buf01;
++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->addr);
++
++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->addr;
++ Error *local_err = NULL;
++ MemoryRegion *mr = NULL;
++ void *ptr_hva;
++
++ ptr_hva = gpa2hva(&mr, gpa, &local_err);
++ if (local_err) {
++ debug(" gpa2hva failed \n");
++ } else {
++ debug(" host virtual address of addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->addr = (void *)ui64_hva;
++ }
++ }
++ break;
++ case VTZF_OPEN_SESSION:
++ debug(" command is VTZF_OPEN_SESSION \n");
++ debug("sizeof(struct_packet_cmd_session) =%d \n", sizeof(struct_packet_cmd_session));
++ debug("sizeof(TC_NS_ClientContext) =%d \n", sizeof(TC_NS_ClientContext));
++ if ( len >= sizeof(struct_packet_cmd_session) ) {
++ struct_packet_cmd_session* vtzf_packet_cmd = (struct_packet_cmd_session *)buf01;
++
++ debug(" vtzf_packet_cmd->cliContext.file_size = 0x%08x, %d \n", vtzf_packet_cmd->cliContext.file_size,
++ vtzf_packet_cmd->cliContext.file_size);
++ debug(" vtzf_packet_cmd->cliContext.file_buffer = 0x%016lx \n", vtzf_packet_cmd->cliContext.file_buffer);
++
++ hwaddr gpa = (uint64_t)vtzf_packet_cmd->cliContext.file_buffer;
++ Error *local_err = NULL;
++ MemoryRegion *mr = NULL;
++ void *ptr_hva;
++
++ ptr_hva = gpa2hva(&mr, gpa, &local_err);
++ if (local_err) {
++ debug(" gpa2hva failed \n");
++ } else {
++ debug(" host virtual address of file_buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++
++ memory_region_unref(mr);
++
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.file_buffer = (void *)ui64_hva;
++ }
++ }
++ break;
++ case VTZF_SEND_CMD:
++ debug(" command is VTZF_SEND_CMD \n");
++ if ( len >= sizeof(struct_vtzf_packet_cmd_send_cmd) ) {
++ struct_vtzf_packet_cmd_send_cmd* vtzf_packet_cmd = (struct_vtzf_packet_cmd_send_cmd *)buf01;
++
++ Error *local_err = NULL;
++ MemoryRegion *mr = NULL;
++ void *ptr_hva;
++
++ uint32_t param_type;
++ bool check_value;
++ hwaddr gpa_param;
++
++ for (i = 0; i < TEEC_PARAM_NUM; i++) {
++ param_type = TEEC_PARAM_TYPE_GET(vtzf_packet_cmd->cliContext.paramTypes, i);
++ check_value = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT);
++ if (IS_TEMP_MEM(param_type)) {
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].memref.buffer failed \n", i);
++ } else {
++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva;
++ }
++
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i);
++ } else {
++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva;
++ }
++
++ } else if (IS_PARTIAL_MEM(param_type)) {
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.buffer;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].memref.buffer failed \n", i);
++ } else {
++ debug(" host virtual address of memref.buffer = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].memref.buffer = ui64_hva;
++ }
++
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].memref.size_addr;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].memref.size_addr failed \n", i);
++ } else {
++ debug(" host virtual address of memref.size_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].memref.size_addr = ui64_hva;
++ }
++
++ } else if (IS_VALUE_MEM(param_type) || check_value) {
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.a_addr;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].value.a_addr failed \n", i);
++ } else {
++ debug(" host virtual address of value.a_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].value.a_addr = ui64_hva;
++ }
++
++ gpa_param = (uint64_t)vtzf_packet_cmd->cliContext.params[i].value.b_addr;
++ ptr_hva = gpa2hva(&mr, gpa_param, &local_err);
++ if (local_err) {
++ debug(" gpa2hva params[%d].value.b_addr failed \n", i);
++ } else {
++ debug(" host virtual address of value.b_addr = 0x%016lx, %p \n", (uint64_t)ptr_hva, ptr_hva);
++ memory_region_unref(mr);
++ uint64_t ui64_hva;
++ ui64_hva = (uint64_t)ptr_hva;
++ vtzf_packet_cmd->cliContext.params[i].value.b_addr = ui64_hva;
++ }
++
++ } else {
++ /* if type is none, ignore it */
++ }
++ }// end for
++
++ }//end if
++ break;
++ default:
++ debug(" other command \n");
++ }
++
++ } // end of if ( len >= 4 )
++
++ ret = qemu_chr_fe_write(&vcon->chr, buf01, len);
+ trace_virtio_console_flush_buf(port->id, len, ret);
+
+ if (ret < len) {
+@@ -304,3 +637,4 @@
+ }
+
+ type_init(virtconsole_register_types)
++
+diff -Naur '--exclude=.git' ./qemu/include/monitor/monitor.h ./qemu_after/include/monitor/monitor.h
+--- ./qemu/include/monitor/monitor.h 2023-08-01 14:07:32.384000000 +0800
++++ ./qemu_after/include/monitor/monitor.h 2023-08-01 14:18:18.664000000 +0800
+@@ -4,6 +4,7 @@
+ #include "block/block.h"
+ #include "qapi/qapi-types-misc.h"
+ #include "qemu/readline.h"
++#include "exec/hwaddr.h"
+
+ extern __thread Monitor *cur_mon;
+ typedef struct MonitorHMP MonitorHMP;
+@@ -36,6 +37,8 @@
+ int monitor_set_cpu(int cpu_index);
+ int monitor_get_cpu_index(void);
+
++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp);
++
+ void monitor_read_command(MonitorHMP *mon, int show_prompt);
+ int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func,
+ void *opaque);
+@@ -49,3 +52,4 @@
+ int64_t monitor_fdset_dup_fd_find(int dup_fd);
+
+ #endif /* MONITOR_H */
++
+diff -Naur '--exclude=.git' ./qemu/monitor/misc.c ./qemu_after/monitor/misc.c
+--- ./qemu/monitor/misc.c 2023-08-01 14:07:32.404000000 +0800
++++ ./qemu_after/monitor/misc.c 2023-08-01 14:18:18.684000000 +0800
+@@ -674,7 +674,7 @@
+ memory_dump(mon, count, format, size, addr, 1);
+ }
+
+-static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp)
++void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp)
+ {
+ MemoryRegionSection mrs = memory_region_find(get_system_memory(),
+ addr, 1);
diff --git a/trustzone-awared-vm/host/tzdriver.patch b/trustzone-awared-vm/host/tzdriver.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4d0c34a558c37f475ca2f3760a7ab2f566298cb9
--- /dev/null
+++ b/trustzone-awared-vm/host/tzdriver.patch
@@ -0,0 +1,1148 @@
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/agent.c ./itrustee_tzdriver_new/core/agent.c
+--- ./itrustee_tzdriver/core/agent.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/agent.c 2023-09-05 13:59:26.880000000 +0800
+@@ -256,13 +256,13 @@
+ uint32_t buf_len = 0;
+ uint8_t *buf_to_tee = NULL;
+ struct mb_cmd_pack *mb_pack = NULL;
+-
++/*
+ ret = check_teecd_auth();
+ if (ret != 0) {
+ tloge("teecd or cadaemon auth failed, ret %d\n", ret);
+ return -EACCES;
+ }
+-
++*/
+ if (!inbuf)
+ return -EINVAL;
+
+@@ -945,6 +945,8 @@
+ nsid = task_active_pid_ns(current)->ns.inum;
+ if (dev_file != NULL && dev_file->nsid == 0)
+ dev_file->nsid = nsid;
++ //if (dev_file->isVM)
++ // nsid = dev_file->nsid;
+ #endif
+
+ if (is_agent_already_exist(agent_id, nsid, &event_data, dev_file, &find_flag))
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/gp_ops.c ./itrustee_tzdriver_new/core/gp_ops.c
+--- ./itrustee_tzdriver/core/gp_ops.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/gp_ops.c 2023-09-05 13:59:26.872000000 +0800
+@@ -312,6 +312,84 @@
+ return 0;
+ }
+
++int read_from_VMclient(void *dest, size_t dest_size,
++ const void __user *src, size_t size, pid_t vm_pid)
++{
++ struct task_struct *vmp_task;
++ int i_rdlen;
++ int i_index;
++ int ret;
++
++ if (!dest || !src) {
++ tloge("src or dest is NULL input buffer\n");
++ return -EINVAL;
++ }
++
++ if (size > dest_size) {
++ tloge("size is larger than dest_size or size is 0\n");
++ return -EINVAL;
++ }
++ if (!size)
++ return 0;
++
++ tlogv("django verbose, execute access_process_vm");
++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID);
++ if (vmp_task == NULL) {
++ tloge("no task for pid %d \n", vm_pid);
++ return -EFAULT;
++ }
++ tlogv("django verbose, task_struct * for pid %d is 0x%px", vm_pid, vmp_task);
++
++ i_rdlen = access_process_vm(vmp_task, (unsigned long)(src), dest, size, FOLL_FORCE);
++ if (i_rdlen != size) {
++ tloge("only read %d of %ld bytes by access_process_vm \n", i_rdlen, size);
++ return -EFAULT;
++ }
++ tlogv("django verbose, read %d byes by access_process_vm succeed",
++ i_rdlen);
++ for (i_index = 0; i_index < 32 && i_index < size; i_index ++) {
++ tlogv("django verbose, *(dest + i_index) + %d) = %2.2x",
++ i_index, *((char*)dest + i_index));
++ }
++ return 0;
++}
++
++int write_to_VMclient(void __user *dest, size_t dest_size,
++ const void *src, size_t size, pid_t vm_pid)
++{
++ struct task_struct *vmp_task;
++ int i_wtlen;
++ int i_index;
++ int ret;
++
++ if (!dest || !src) {
++ tloge("src or dest is NULL input buffer\n");
++ return -EINVAL;
++ }
++
++ if (size > dest_size) {
++ tloge("size is larger than dest_size or size is 0\n");
++ return -EINVAL;
++ }
++ if (!size)
++ return 0;
++
++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID);
++ if (vmp_task == NULL) {
++ tloge("no task for pid %d \n", vm_pid);
++ return -EFAULT;
++ }
++
++ i_wtlen = access_process_vm(vmp_task, (unsigned long)(dest), src, size, FOLL_FORCE | FOLL_WRITE);
++ if (i_wtlen != size) {
++ tloge("only write %d of %ld bytes by access_process_vm \n", i_wtlen, size);
++ return -EFAULT;
++ }
++ tlogv("django verbose, write %d byes by access_process_vm succeed",
++ i_wtlen);
++ return 0;
++}
++
+ static bool is_input_tempmem(unsigned int param_type)
+ {
+ if (param_type == TEEC_MEMREF_TEMP_INPUT ||
+@@ -321,7 +399,8 @@
+ return false;
+ }
+
+-static int update_input_data(const union tc_ns_client_param *client_param,
++static int update_input_data(const struct tc_call_params *call_params,
++ const union tc_ns_client_param *client_param,
+ uint32_t buffer_size, void *temp_buf,
+ unsigned int param_type, uint8_t kernel_params)
+ {
+@@ -331,11 +410,22 @@
+
+ buffer_addr = client_param->memref.buffer |
+ ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM);
+- if (read_from_client(temp_buf, buffer_size,
+- (void *)(uintptr_t)buffer_addr,
+- buffer_size, kernel_params) != 0) {
+- tloge("copy memref buffer failed\n");
+- return -EFAULT;
++ if (call_params->dev->isVM && !kernel_params) {
++ tlogd("is VM\n");
++ if (read_from_VMclient(temp_buf, buffer_size,
++ (void *)(uintptr_t)buffer_addr,
++ buffer_size, call_params->dev->vmpid) != 0) {
++ tloge("copy memref buffer failed\n");
++ return -EFAULT;
++ }
++ } else {
++ tlogd("is not VM\n");
++ if (read_from_client(temp_buf, buffer_size,
++ (void *)(uintptr_t)buffer_addr,
++ buffer_size, kernel_params) != 0) {
++ tloge("copy memref buffer failed\n");
++ return -EFAULT;
++ }
+ }
+ return 0;
+ }
+@@ -361,11 +451,22 @@
+ client_param = &(call_params->context->params[index]);
+ size_addr = client_param->memref.size_addr |
+ ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM);
+- if (read_from_client(&buffer_size, sizeof(buffer_size),
+- (uint32_t __user *)(uintptr_t)size_addr,
+- sizeof(uint32_t), kernel_params) != 0) {
+- tloge("copy memref.size_addr failed\n");
+- return -EFAULT;
++ if (call_params->dev->isVM && !kernel_params) {
++ tlogd(" is VM\n ");
++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), call_params->dev->vmpid) != 0) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
++ } else{
++ tlogd(" is not VM ");
++ if (read_from_client(&buffer_size, sizeof(buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), kernel_params) != 0) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
+ }
+
+ if (buffer_size > MAX_SHARED_SIZE) {
+@@ -393,7 +494,7 @@
+ op_params->local_tmpbuf[index].temp_buffer = temp_buf;
+ op_params->local_tmpbuf[index].size = buffer_size;
+
+- if (update_input_data(client_param, buffer_size, temp_buf,
++ if (update_input_data(call_params, client_param, buffer_size, temp_buf,
+ param_type, kernel_params) != 0)
+ return -EFAULT;
+
+@@ -405,17 +506,31 @@
+ return 0;
+ }
+
+-static int check_buffer_for_ref(uint32_t *buffer_size,
+- const union tc_ns_client_param *client_param, uint8_t kernel_params)
++static int check_buffer_for_ref(const struct tc_call_params *call_params,
++ uint32_t *buffer_size, const union tc_ns_client_param *client_param,
++ uint8_t kernel_params)
+ {
+ uint64_t size_addr = client_param->memref.size_addr |
+ ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM);
+- if (read_from_client(buffer_size, sizeof(*buffer_size),
+- (uint32_t __user *)(uintptr_t)size_addr,
+- sizeof(uint32_t), kernel_params) != 0) {
+- tloge("copy memref.size_addr failed\n");
+- return -EFAULT;
++
++ if (call_params->dev->isVM && !kernel_params) {
++ tlogd("is VM\n");
++ if (read_from_VMclient(buffer_size, sizeof(*buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), call_params->dev->vmpid) != 0) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
++ } else {
++ tlogd("is not VM\n");
++ if (read_from_client(buffer_size, sizeof(*buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), kernel_params) != 0) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
+ }
++
+ if (*buffer_size == 0) {
+ tloge("buffer_size from user is 0\n");
+ return -ENOMEM;
+@@ -497,7 +612,7 @@
+ return -EINVAL;
+
+ client_param = &(call_params->context->params[index]);
+- if (check_buffer_for_ref(&buffer_size, client_param, kernel_params) != 0)
++ if (check_buffer_for_ref(call_params, &buffer_size, client_param, kernel_params) != 0)
+ return -EINVAL;
+
+ op_params->mb_pack->operation.params[index].memref.buffer = 0;
+@@ -546,17 +661,27 @@
+
+ #ifdef CONFIG_NOCOPY_SHAREDMEM
+ static int check_buffer_for_sharedmem(uint32_t *buffer_size,
+- const union tc_ns_client_param *client_param, uint8_t kernel_params)
++ const union tc_ns_client_param *client_param, uint8_t kernel_params, struct tc_ns_dev_file *dev_file)
+ {
+ uint64_t size_addr = client_param->memref.size_addr |
+ ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM);
+ uint64_t buffer_addr = client_param->memref.buffer |
+ ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM);
+- if (read_from_client(buffer_size, sizeof(*buffer_size),
+- (uint32_t __user *)(uintptr_t)size_addr,
+- sizeof(uint32_t), kernel_params)) {
+- tloge("copy size_addr failed\n");
+- return -EFAULT;
++ if (dev_file->isVM && !kernel_params) {
++ tlogd("is VM\n");
++ if (read_from_VMclient(buffer_size, sizeof(*buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), dev_file->vmpid) != 0) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
++ } else {
++ if (read_from_client(buffer_size, sizeof(*buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), kernel_params)) {
++ tloge("copy size_addr failed\n");
++ return -EFAULT;
++ }
+ }
+
+ if (*buffer_size == 0 || *buffer_size > SZ_256M) {
+@@ -572,6 +697,96 @@
+ return 0;
+ }
+
++
++void put_vm_pages(struct page **pages, uint32_t page_num)
++{
++ int i;
++ for (i = 0; i < page_num; i++) {
++ if (pages[i]) {
++ put_page(pages[i]);
++ pages[i] = NULL;
++ }
++ }
++}
++
++int fill_vm_shared_mem_info(uint64_t start_vaddr, uint32_t pages_no,
++ uint32_t offset, uint32_t buffer_size, uint64_t info_addr, pid_t vm_pid)
++{
++ struct pagelist_info *page_info = NULL;
++ struct page **pages = NULL;
++ uint64_t *phys_addr = NULL;
++ uint32_t page_num;
++ uint32_t i;
++ struct task_struct *vmp_task;
++
++ if (pages_no == 0)
++ return -EFAULT;
++
++ pages = (struct page **)vmalloc(pages_no * sizeof(uint64_t));
++ if (pages == NULL)
++ return -EFAULT;
++
++ vmp_task = get_pid_task(find_get_pid(vm_pid), PIDTYPE_PID);
++ if (vmp_task == NULL) {
++ tloge("no task for pid %d", vm_pid);
++ return -EFAULT;
++ }
++
++#if (KERNEL_VERSION(6, 5, 0) <= LINUX_VERSION_CODE)
++ page_num = get_user_pages_remote(vmp_task->mm, start_vaddr,
++ (unsigned long)pages_no,
++ FOLL_FORCE, pages, NULL);
++#elif (KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE)
++ page_num = get_user_pages_remote(vmp_task->mm, start_vaddr,
++ (unsigned long)pages_no,
++ FOLL_FORCE, pages,
++ NULL, NULL);
++#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm,
++ start_vaddr, (unsigned long)pages_no, FOLL_FORCE,
++ pages, NULL, NULL);
++#elif (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE)
++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm,
++ start_vaddr, (unsigned long)pages_no,
++ FOLL_FORCE, pages, NULL);
++#else
++ page_num = get_user_pages_remote(vmp_task, vmp_task->mm,
++ start_vaddr, (unsigned long)pages_no,
++ 1, 1, pages, NULL);
++
++#endif
++ if (page_num != pages_no) {
++ tloge("get page phy addr failed\n");
++ if (page_num > 0)
++ put_vm_pages(pages, page_num);
++ vfree(pages);
++ return -EFAULT;
++ }
++ tlogd("get_user pages remote success, page num = %u , page_size = %d \n", page_num, PAGE_SIZE);
++
++ page_info = (struct pagelist_info *)(uintptr_t)info_addr;
++ page_info->page_num = pages_no;
++ page_info->page_size = PAGE_SIZE;
++ page_info->sharedmem_offset = offset;
++ page_info->sharedmem_size = buffer_size;
++
++ phys_addr = (uint64_t *)(uintptr_t)info_addr + (sizeof(*page_info) / sizeof(uint64_t));
++ for (i = 0; i < pages_no; i++) {
++ struct page *page = NULL;
++ page = pages[i];
++ if (page == NULL) {
++ put_vm_pages(pages, page_num);
++ vfree(pages);
++ tloge("page == NULL \n");
++ return -EFAULT;
++ }
++ phys_addr[i] = (uintptr_t)page_to_phys(page);
++ }
++
++ vfree(pages);
++ return 0;
++}
++
+ static int transfer_shared_mem(const struct tc_call_params *call_params,
+ struct tc_op_params *op_params, uint8_t kernel_params,
+ uint32_t param_type, unsigned int index)
+@@ -589,7 +804,7 @@
+ return -EINVAL;
+
+ client_param = &(call_params->context->params[index]);
+- if (check_buffer_for_sharedmem(&buffer_size, client_param, kernel_params))
++ if (check_buffer_for_sharedmem(&buffer_size, client_param, kernel_params, call_params->dev))
+ return -EINVAL;
+
+ buffer_addr = client_param->memref.buffer |
+@@ -603,10 +818,18 @@
+ buff = mailbox_alloc(buff_len, MB_FLAG_ZERO);
+ if (buff == NULL)
+ return -EFAULT;
+-
+- if (fill_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff)) {
+- mailbox_free(buff);
+- return -EFAULT;
++ if (call_params->dev->isVM) {
++ tlogd("pages_no = %u, buffer_addr = %lx, offset = %x \n", pages_no, buffer_addr, offset);
++ tlogd("PAGE_SIZE = %x , PAGE_MASK = %x \n", PAGE_SIZE, PAGE_MASK);
++ if (fill_vm_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff, call_params->dev->vmpid)) {
++ mailbox_free(buff);
++ return -EFAULT;
++ }
++ } else {
++ if (fill_shared_mem_info((uint64_t)start_vaddr, pages_no, offset, buffer_size, (uint64_t)buff)) {
++ mailbox_free(buff);
++ return -EFAULT;
++ }
+ }
+
+ op_params->local_tmpbuf[index].temp_buffer = buff;
+@@ -651,21 +874,42 @@
+ b_addr = client_param->value.b_addr |
+ ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM);
+
+- if (read_from_client(&operation->params[index].value.a,
+- sizeof(operation->params[index].value.a),
+- (void *)(uintptr_t)a_addr,
+- sizeof(operation->params[index].value.a),
+- kernel_params) != 0) {
+- tloge("copy valuea failed\n");
+- return -EFAULT;
+- }
+- if (read_from_client(&operation->params[index].value.b,
+- sizeof(operation->params[index].value.b),
+- (void *)(uintptr_t)b_addr,
+- sizeof(operation->params[index].value.b),
+- kernel_params) != 0) {
+- tloge("copy valueb failed\n");
+- return -EFAULT;
++ if (call_params->dev->isVM && !kernel_params) {
++ tlogd("is VM \n");
++ if (read_from_VMclient(&operation->params[index].value.a,
++ sizeof(operation->params[index].value.a),
++ (void *)(uintptr_t)a_addr,
++ sizeof(operation->params[index].value.a),
++ call_params->dev->vmpid) != 0) {
++ tloge("copy valuea failed\n");
++ return -EFAULT;
++ }
++ if (read_from_VMclient(&operation->params[index].value.b,
++ sizeof(operation->params[index].value.b),
++ (void *)(uintptr_t)b_addr,
++ sizeof(operation->params[index].value.b),
++ call_params->dev->vmpid) != 0) {
++ tloge("copy valueb failed\n");
++ return -EFAULT;
++ }
++ } else {
++ tlogd("is not VM \n");
++ if (read_from_client(&operation->params[index].value.a,
++ sizeof(operation->params[index].value.a),
++ (void *)(uintptr_t)a_addr,
++ sizeof(operation->params[index].value.a),
++ kernel_params) != 0) {
++ tloge("copy valuea failed\n");
++ return -EFAULT;
++ }
++ if (read_from_client(&operation->params[index].value.b,
++ sizeof(operation->params[index].value.b),
++ (void *)(uintptr_t)b_addr,
++ sizeof(operation->params[index].value.b),
++ kernel_params) != 0) {
++ tloge("copy valueb failed\n");
++ return -EFAULT;
++ }
+ }
+
+ /* TEEC_VALUE_INPUT equal to TEE_PARAM_TYPE_VALUE_INPUT */
+@@ -754,12 +998,24 @@
+ buffer_addr = client_param->memref.buffer |
+ ((uint64_t)client_param->memref.buffer_h_addr << ADDR_TRANS_NUM);
+ /* Size is updated all the time */
+- if (write_to_client((void *)(uintptr_t)size_addr,
+- sizeof(buffer_size),
+- &buffer_size, sizeof(buffer_size),
+- call_params->dev->kernel_api) != 0) {
+- tloge("copy tempbuf size failed\n");
+- return -EFAULT;
++ if (call_params->dev->isVM && !call_params->dev->kernel_api) {
++ tlogd("is VM\n");
++ if (write_to_VMclient((void *)(uintptr_t)size_addr,
++ sizeof(buffer_size),
++ &buffer_size, sizeof(buffer_size),
++ call_params->dev->vmpid) != 0) {
++ tloge("copy tempbuf size failed\n");
++ return -EFAULT;
++ }
++ }else{
++ tlogd("is not VM\n");
++ if (write_to_client((void *)(uintptr_t)size_addr,
++ sizeof(buffer_size),
++ &buffer_size, sizeof(buffer_size),
++ call_params->dev->kernel_api) != 0) {
++ tloge("copy tempbuf size failed\n");
++ return -EFAULT;
++ }
+ }
+ if (buffer_size > op_params->local_tmpbuf[index].size) {
+ /* incomplete case, when the buffer size is invalid see next param */
+@@ -775,13 +1031,26 @@
+ if (buffer_size == 0)
+ return 0;
+ /* Only update the buffer when the buffer size is valid in complete case */
+- if (write_to_client((void *)(uintptr_t)buffer_addr,
+- operation->params[index].memref.size,
+- op_params->local_tmpbuf[index].temp_buffer,
+- operation->params[index].memref.size,
+- call_params->dev->kernel_api) != 0) {
+- tloge("copy tempbuf failed\n");
+- return -ENOMEM;
++ if (call_params->dev->isVM && !call_params->dev->kernel_api) {
++ tlogd("is VM\n");
++ if (write_to_VMclient((void *)(uintptr_t)buffer_addr,
++ operation->params[index].memref.size,
++ op_params->local_tmpbuf[index].temp_buffer,
++ operation->params[index].memref.size,
++ call_params->dev->vmpid) != 0) {
++ tloge("copy tempbuf failed\n");
++ return -ENOMEM;
++ }
++ } else {
++ tlogd("is not VM\n");
++ if (write_to_client((void *)(uintptr_t)buffer_addr,
++ operation->params[index].memref.size,
++ op_params->local_tmpbuf[index].temp_buffer,
++ operation->params[index].memref.size,
++ call_params->dev->kernel_api) != 0) {
++ tloge("copy tempbuf failed\n");
++ return -ENOMEM;
++ }
+ }
+ return 0;
+ }
+@@ -806,22 +1075,38 @@
+ size_addr = client_param->memref.size_addr |
+ ((uint64_t)client_param->memref.size_h_addr << ADDR_TRANS_NUM);
+
+- if (read_from_client(&orig_size,
+- sizeof(orig_size),
+- (uint32_t __user *)(uintptr_t)size_addr,
+- sizeof(orig_size), call_params->dev->kernel_api) != 0) {
+- tloge("copy orig memref.size_addr failed\n");
+- return -EFAULT;
+- }
++ if (call_params->dev->isVM && !call_params->dev->kernel_api) {
++ if (read_from_VMclient(&orig_size, sizeof(orig_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(orig_size), call_params->dev->vmpid) != 0) {
++ tloge("copy orig memref.size_addr failed\n");
++ return -EFAULT;
++ }
++
++ if (write_to_VMclient((void *)(uintptr_t)size_addr,
++ sizeof(buffer_size),
++ &buffer_size, sizeof(buffer_size),
++ call_params->dev->vmpid) != 0) {
++ tloge("copy buf size failed\n");
++ return -EFAULT;
++ }
++ } else {
++ if (read_from_client(&orig_size,
++ sizeof(orig_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(orig_size), call_params->dev->kernel_api) != 0) {
++ tloge("copy orig memref.size_addr failed\n");
++ return -EFAULT;
++ }
+
+- if (write_to_client((void *)(uintptr_t)size_addr,
+- sizeof(buffer_size),
+- &buffer_size, sizeof(buffer_size),
+- call_params->dev->kernel_api) != 0) {
+- tloge("copy buf size failed\n");
+- return -EFAULT;
++ if (write_to_client((void *)(uintptr_t)size_addr,
++ sizeof(buffer_size),
++ &buffer_size, sizeof(buffer_size),
++ call_params->dev->kernel_api) != 0) {
++ tloge("copy buf size failed\n");
++ return -EFAULT;
++ }
+ }
+-
+ /* reserved memory no need to copy */
+ if (operation->sharemem[index]->mem_type == RESERVED_TYPE)
+ return 0;
+@@ -859,21 +1144,42 @@
+ b_addr = client_param->value.b_addr |
+ ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM);
+
+- if (write_to_client((void *)(uintptr_t)a_addr,
+- sizeof(operation->params[index].value.a),
+- &operation->params[index].value.a,
+- sizeof(operation->params[index].value.a),
+- call_params->dev->kernel_api) != 0) {
+- tloge("inc copy value.a_addr failed\n");
+- return -EFAULT;
+- }
+- if (write_to_client((void *)(uintptr_t)b_addr,
+- sizeof(operation->params[index].value.b),
+- &operation->params[index].value.b,
+- sizeof(operation->params[index].value.b),
+- call_params->dev->kernel_api) != 0) {
+- tloge("inc copy value.b_addr failed\n");
+- return -EFAULT;
++ if (call_params->dev->isVM && !call_params->dev->kernel_api) {
++ tlogd("is VM \n");
++ if (write_to_VMclient((void *)(uintptr_t)a_addr,
++ sizeof(operation->params[index].value.a),
++ &operation->params[index].value.a,
++ sizeof(operation->params[index].value.a),
++ call_params->dev->vmpid) != 0) {
++ tloge("inc copy value.a_addr failed\n");
++ return -EFAULT;
++ }
++ if (write_to_VMclient((void *)(uintptr_t)b_addr,
++ sizeof(operation->params[index].value.b),
++ &operation->params[index].value.b,
++ sizeof(operation->params[index].value.b),
++ call_params->dev->vmpid) != 0) {
++ tloge("inc copy value.b_addr failed\n");
++ return -EFAULT;
++ }
++ } else {
++ tlogd("is not VM\n");
++ if (write_to_client((void *)(uintptr_t)a_addr,
++ sizeof(operation->params[index].value.a),
++ &operation->params[index].value.a,
++ sizeof(operation->params[index].value.a),
++ call_params->dev->kernel_api) != 0) {
++ tloge("inc copy value.a_addr failed\n");
++ return -EFAULT;
++ }
++ if (write_to_client((void *)(uintptr_t)b_addr,
++ sizeof(operation->params[index].value.b),
++ &operation->params[index].value.b,
++ sizeof(operation->params[index].value.b),
++ call_params->dev->kernel_api) != 0) {
++ tloge("inc copy value.b_addr failed\n");
++ return -EFAULT;
++ }
+ }
+ return 0;
+ }
+@@ -1248,3 +1554,7 @@
+ release_tc_call_resource(call_params, &op_params, tee_ret);
+ return ret;
+ }
++
++
++
++
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/gp_ops.h ./itrustee_tzdriver_new/core/gp_ops.h
+--- ./itrustee_tzdriver/core/gp_ops.h 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/gp_ops.h 2023-09-05 13:59:26.880000000 +0800
+@@ -30,5 +30,9 @@
+ bool is_tmp_mem(uint32_t param_type);
+ bool is_ref_mem(uint32_t param_type);
+ bool is_val_param(uint32_t param_type);
++int write_to_VMclient(void __user *dest, size_t dest_size,
++ const void *src, size_t size, pid_t vm_pid);
++int read_from_VMclient(void *dest, size_t dest_size,
++ const void __user *src, size_t size, pid_t vm_pid);
+
+ #endif
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/session_manager.c ./itrustee_tzdriver_new/core/session_manager.c
+--- ./itrustee_tzdriver/core/session_manager.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/session_manager.c 2023-09-05 13:59:26.872000000 +0800
+@@ -792,16 +792,30 @@
+ if (memcpy_s(params->mb_load_mem + sizeof(load_flag),
+ params->mb_load_size - sizeof(load_flag),
+ params->file_buffer + loaded_size, load_size) != 0) {
+- tloge("memcpy file buf get fail\n");
++ tloge("memcpy file buf get failed \n");
+ return -EFAULT;
+ }
+ return 0;
+ }
+- if (copy_from_user(params->mb_load_mem + sizeof(load_flag),
+- (const void __user *)params->file_buffer + loaded_size, load_size)) {
+- tloge("file buf get fail\n");
+- return -EFAULT;
++
++ if (params->dev_file->isVM) {
++ tlogd("is VM \n");
++ if (read_from_VMclient(params->mb_load_mem + sizeof(load_flag),
++ load_size, (const void __user *)params->file_buffer + loaded_size,
++ load_size, (pid_t)params->dev_file->vmpid)) {
++ tloge("file buf get failed \n");
++ tlogd("file buf get failed \n");
++ return -EFAULT;
++ }
++ } else {
++ tlogd("is not VM \n");
++ if (copy_from_user(params->mb_load_mem + sizeof(load_flag),
++ (const void __user *)params->file_buffer + loaded_size, load_size)) {
++ tloge("file buf get failed \n");
++ return -EFAULT;
++ }
+ }
++
+ return 0;
+ }
+
+@@ -830,10 +844,8 @@
+ params->mb_load_size);
+ return -EINVAL;
+ }
+-
+ if (load_image_copy_file(params, load_size, load_flag, loaded_size) != 0)
+ return -EFAULT;
+-
+ pack_load_frame_cmd(load_size, params, &smc_cmd);
+ params->mb_pack->operation.params[3].value.a = index;
+ params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type;
+@@ -845,8 +857,9 @@
+ tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n",
+ params->mb_pack->operation.params[1].value.a, smc_ret,
+ load_flag, index);
+-
++ tlogd("after tc_ns_smc \n");
+ if (smc_ret != 0) {
++ tloge("smc_ret = %d \n",smc_ret);
+ if (tee_ret != NULL) {
+ tee_ret->code = smc_ret;
+ tee_ret->origin = smc_cmd.err_origin;
+@@ -857,7 +870,7 @@
+
+ if (!smc_ret && !load_flag && load_image_for_ion(params, tee_ret ? &tee_ret->origin : NULL))
+ return -EPERM;
+-
++ tlogd("before return \n");
+ loaded_size += load_size;
+ }
+ return 0;
+@@ -1379,10 +1392,126 @@
+ return ret;
+ }
+
++static int process_vm_ref(struct tc_ns_dev_file *dev_file,
++ struct tc_ns_client_context *context, unsigned long long *vm_buffers,
++ unsigned long long *kn_buffers)
++{
++ struct tc_ns_shared_mem *shared_mem = NULL;
++ int index = 0;
++ uint32_t buffer_size;
++ unsigned int offset = 0;
++ void *buffer_addr = NULL;
++ void *size_addr = NULL;
++ unsigned long long vm_hvas[TEE_PARAM_NUM]={0};
++
++ if (!dev_file->isVM)
++ return 0;
++ if (!context->file_buffer) {
++ return 0;
++ }
++
++ if (copy_from_user(vm_hvas, context->file_buffer, context->file_size) != 0) {
++ tloge("copy from user failed\n");
++ return -EFAULT;
++ }
++
++ mutex_lock(&dev_file->shared_mem_lock);
++ list_for_each_entry(shared_mem, &dev_file->shared_mem_list, head) {
++ for (index = 0; index < TEE_PARAM_NUM; index++) {
++ buffer_addr = (void *)(uintptr_t)(context->params[index].memref.buffer |
++ ((uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM));
++ if (shared_mem->user_addr == buffer_addr) {
++ buffer_addr = (void *)(uintptr_t)(shared_mem->kernel_addr);
++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr |
++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM));
++ offset = context->params[index].memref.offset;
++
++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), dev_file->vmpid)) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
++ tlogv(" buffer_size = %d \n", buffer_size);
++ tlogv(" ");
++
++ if (read_from_VMclient(buffer_addr + offset, buffer_size,
++ (uint32_t __user *)(uintptr_t)(vm_hvas[index] + offset),
++ buffer_size, dev_file->vmpid)) {
++ tloge("copy memref.buffer failed\n");
++ return -EFAULT;
++ }
++ vm_buffers[index] = vm_hvas[index];
++ kn_buffers[index] = (unsigned long long)buffer_addr;
++ }
++ }
++ }
++ mutex_unlock(&dev_file->shared_mem_lock);
++ return 0;
++}
++
++static int process_vm_ref_end(struct tc_ns_dev_file *dev_file,
++ struct tc_ns_client_context *context, unsigned long long *vm_buffers,
++ unsigned long long *kn_buffers)
++{
++ int ret = 0;
++ int index = 0;
++ uint32_t buffer_size;
++ unsigned int offset = 0;
++ void *size_addr = NULL;
++
++ if (!dev_file->isVM)
++ return 0;
++
++ for (index = 0; index < TEE_PARAM_NUM; index++)
++ {
++ if (kn_buffers[index] != 0 && vm_buffers[index] != 0) {
++ size_addr = (void *)(uintptr_t)(context->params[index].memref.size_addr |
++ ((uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM));
++
++ if (read_from_VMclient(&buffer_size, sizeof(buffer_size),
++ (uint32_t __user *)(uintptr_t)size_addr,
++ sizeof(uint32_t), dev_file->vmpid)) {
++ tloge("copy memref.size_addr failed\n");
++ return -EFAULT;
++ }
++ offset = context->params[index].memref.offset;
++
++ tlogv("<--------------------\n");
++ tlogv(" buffer_size = %d \n", buffer_size);
++ tlogv(" vm_buffers[index] = 0x%16.16lx", (long unsigned int)(vm_buffers[index]));
++ tlogv(" *(kn_buffers[index] + offset) = %s \n", (char*)(kn_buffers[index] + offset));
++ tlogv(" offset = %ld \n", (long unsigned int)offset);
++ tlogv("-------------------->\n");
++
++ if (write_to_VMclient((void *)(uintptr_t)(vm_buffers[index] + offset),
++ buffer_size, (void *)(uintptr_t)(kn_buffers[index] + offset),
++ buffer_size, dev_file->vmpid)) {
++ tloge("copy buf size failed\n");
++ return -EFAULT;
++ }
++
++ } else if (kn_buffers[index] == 0 && vm_buffers[index] == 0) {
++ /* do nothing*/
++ ;
++ } else {
++ return -EFAULT;
++ }
++ }
++ return ret;
++}
++
+ static int ioctl_session_send_cmd(struct tc_ns_dev_file *dev_file,
+ struct tc_ns_client_context *context, void *argp)
+ {
+ int ret;
++ unsigned long long vm_buffers[TEE_PARAM_NUM]={0};
++ unsigned long long kn_buffers[TEE_PARAM_NUM]={0};
++
++ if (process_vm_ref(dev_file, context, vm_buffers, kn_buffers)) {
++ tloge("copy VM memref failed\n");
++ return -EFAULT;
++ }
+
+ ret = tc_ns_send_cmd(dev_file, context);
+ if (ret != 0)
+@@ -1391,6 +1520,11 @@
+ if (ret == 0)
+ ret = -EFAULT;
+ }
++
++ if (process_vm_ref_end(dev_file, context, vm_buffers, kn_buffers)) {
++ tloge("copy VM memref failed\n");
++ return -EFAULT;
++ }
+ return ret;
+ }
+
+@@ -1516,3 +1650,6 @@
+ mutex_unlock(&dev_list->dev_lock);
+ return;
+ }
++
++
++
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/smc_smp.c ./itrustee_tzdriver_new/core/smc_smp.c
+--- ./itrustee_tzdriver/core/smc_smp.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/smc_smp.c 2023-09-05 13:59:26.880000000 +0800
+@@ -1771,7 +1771,9 @@
+ release_pending_entry(pe);
+ return TEEC_ERROR_GENERIC;
+ }
+-
++ tlogd("---------------------------\n");
++ tlogd("cmd.nsid = %d \n", cmd.nsid);
++ tlogd("---------------------------\n");
+ if (smp_smc_send_process(&cmd, ops, &cmd_ret, info.cmd_index) == -1)
+ goto clean;
+
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/tc_client_driver.c ./itrustee_tzdriver_new/core/tc_client_driver.c
+--- ./itrustee_tzdriver/core/tc_client_driver.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/tc_client_driver.c 2023-09-05 14:28:58.236000000 +0800
+@@ -307,12 +307,12 @@
+
+ static int tc_login_check(const struct tc_ns_dev_file *dev_file)
+ {
+- int ret = check_teecd_auth();
++/* int ret = check_teecd_auth();
+ if (ret != 0) {
+ tloge("teec auth failed, ret %d\n", ret);
+ return -EACCES;
+ }
+-
++*/
+ if (!dev_file)
+ return -EINVAL;
+
+@@ -694,12 +694,55 @@
+ return 0;
+ }
+
++static int copy_buf_to_VM(unsigned int agent_id, unsigned int nsid,
++ unsigned long buffer_addr, unsigned int vmpid)
++{
++ int ret = 0;
++ struct smc_event_data *event_data = NULL;
++
++ event_data = find_event_control(agent_id, nsid);
++ if (!event_data)
++ return -EINVAL;
++
++ if (write_to_VMclient((void *)(uintptr_t)buffer_addr,
++ event_data->agent_buff_size,
++ event_data->agent_buff_kernel,
++ event_data->agent_buff_size,
++ vmpid) != 0) {
++ tloge("copy agent buffer failed\n");
++ return -ENOMEM;
++ }
++ return ret;
++}
++
++static int copy_buf_from_VM(unsigned int agent_id, unsigned int nsid,
++ unsigned long buffer_addr, unsigned int vmpid)
++{
++ int ret = 0;
++ struct smc_event_data *event_data = NULL;
++
++ event_data = find_event_control(agent_id, nsid);
++ if (!event_data)
++ return -EINVAL;
++
++ if (read_from_VMclient(event_data->agent_buff_kernel,
++ event_data->agent_buff_size,
++ (void *)(uintptr_t)buffer_addr,
++ event_data->agent_buff_size,
++ vmpid) != 0) {
++ tloge("copy agent buffer failed\n");
++ return -EFAULT;
++ }
++ return ret;
++}
++
+ /* ioctls for the secure storage daemon */
+ int public_ioctl(const struct file *file, unsigned int cmd, unsigned long arg, bool is_from_client_node)
+ {
+ int ret = -EINVAL;
+ struct tc_ns_dev_file *dev_file = NULL;
+ uint32_t nsid = get_nsid();
++ unsigned long tmp[2];
+ void *argp = (void __user *)(uintptr_t)arg;
+ if (file == NULL || file->private_data == NULL) {
+ tloge("invalid params\n");
+@@ -707,18 +750,35 @@
+ }
+ dev_file = file->private_data;
+ #ifdef CONFIG_CONFIDENTIAL_CONTAINER
+- dev_file->nsid = nsid;
++ if (dev_file != NULL && dev_file->nsid == 0)
++ dev_file->nsid = nsid;
++ //if (dev_file->isVM)
++ // nsid = dev_file->nsid;
+ #endif
+
++ if (dev_file->isVM) {
++ if (copy_from_user(tmp, (void *)(uintptr_t)arg, sizeof(tmp)) != 0) {
++ tloge("copy agent args failed\n");
++ return -EFAULT;
++ }
++ arg = tmp[0];
++ }
++ tlogd("nsid = %u, dev_file->nsid = %u \n", nsid, dev_file->nsid);
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_WAIT_EVENT:
+ if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0)
+ return -EINVAL;
+ ret = tc_ns_wait_event((unsigned int)arg, nsid);
++ if (!ret && dev_file->isVM) {
++ ret = copy_buf_to_VM(tmp[0], nsid, tmp[1], dev_file->vmpid);
++ }
+ break;
+ case TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE:
+ if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0)
+ return -EINVAL;
++ if (dev_file->isVM) {
++ ret = copy_buf_from_VM(tmp[0], nsid, tmp[1], dev_file->vmpid);
++ }
+ ret = tc_ns_send_event_response((unsigned int)arg, nsid);
+ break;
+ case TC_NS_CLIENT_IOCTL_REGISTER_AGENT:
+@@ -796,12 +856,12 @@
+ case TC_NS_CLIENT_IOCTL_WAIT_EVENT:
+ case TC_NS_CLIENT_IOCTL_REGISTER_AGENT:
+ case TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT:
+- if (get_agent_id(arg, cmd, &agent_id) != 0)
++ /* if (get_agent_id(arg, cmd, &agent_id) != 0)
+ return ret;
+ if (check_ext_agent_access(agent_id) != 0) {
+ tloge("the agent is not access\n");
+ return -EPERM;
+- }
++ }*/
+ ret = public_ioctl(file, cmd, arg, true);
+ break;
+ default:
+@@ -812,6 +872,19 @@
+ return ret;
+ }
+
++int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid)
++{
++ dev_file->isVM = true;
++ tlogd(" dev_file->isVM %d\n", (int)dev_file->isVM);
++ dev_file->vmpid = vmid;
++ tlogd(" dev_file->vmpid %d\n", (int)dev_file->vmpid);
++ tlogd("------------------\n");
++ tlogd("task_active_pid_ns(current)->ns.inum = %u \n", task_active_pid_ns(current)->ns.inum);
++ tlogd("PROC_PID_INIT_INO = %u\n", PROC_PID_INIT_INO);
++ tlogd("------------------\n");
++ return 0;
++}
++
+ void handle_cmd_prepare(unsigned int cmd)
+ {
+ if (cmd != TC_NS_CLIENT_IOCTL_WAIT_EVENT &&
+@@ -831,6 +904,10 @@
+ {
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) {
++ tlogd(" before set_vm_flag \n");
++ return set_vm_flag(file->private_data, (int)arg);
++ }
+ handle_cmd_prepare(cmd);
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION:
+@@ -866,7 +943,10 @@
+ {
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
+-
++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) {
++ tlogd(" before set_vm_flag \n");
++ return set_vm_flag(file->private_data, (int)arg);
++ }
+ handle_cmd_prepare(cmd);
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ:
+@@ -899,13 +979,13 @@
+ int ret;
+ struct tc_ns_dev_file *dev = NULL;
+ (void)inode;
+-
++/*
+ ret = check_teecd_auth();
+ if (ret != 0) {
+ tloge("teec auth failed, ret %d\n", ret);
+ return -EACCES;
+ }
+-
++*/
+ file->private_data = NULL;
+ ret = tc_ns_client_open(&dev, TEE_REQ_FROM_USER_MODE);
+ if (ret == 0)
+@@ -1442,3 +1522,5 @@
+ #endif
+ module_exit(tc_exit);
+ MODULE_LICENSE("GPL");
++
++
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/tc_client_driver.h ./itrustee_tzdriver_new/core/tc_client_driver.h
+--- ./itrustee_tzdriver/core/tc_client_driver.h 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/tc_client_driver.h 2023-09-05 13:59:26.880000000 +0800
+@@ -38,6 +38,7 @@
+ int tc_ns_client_close(struct tc_ns_dev_file *dev);
+ int is_agent_alive(unsigned int agent_id, unsigned int nsid);
+ int tc_ns_register_host_nsid(void);
++int set_vm_flag(struct tc_ns_dev_file *dev_file, int vmid);
+
+ #if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ const struct file_operations *get_cvm_fops(void);
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/core/tc_cvm_driver.c ./itrustee_tzdriver_new/core/tc_cvm_driver.c
+--- ./itrustee_tzdriver/core/tc_cvm_driver.c 2023-08-03 17:22:25.908000000 +0800
++++ ./itrustee_tzdriver_new/core/tc_cvm_driver.c 2023-09-05 14:23:42.804000000 +0800
+@@ -57,6 +57,10 @@
+ {
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
++ if (cmd == TC_NS_CLIENT_IOCTL_SET_VM_FLAG) {
++ tlogd(" before set_vm_flag \n");
++ return set_vm_flag(file->private_data, (int)arg);
++ }
+ handle_cmd_prepare(cmd);
+
+ switch (cmd) {
+@@ -137,3 +141,4 @@
+ return &g_cvm_fops;
+ }
+ #endif
++
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/tc_ns_client.h ./itrustee_tzdriver_new/tc_ns_client.h
+--- ./itrustee_tzdriver/tc_ns_client.h 2023-08-03 17:22:25.912000000 +0800
++++ ./itrustee_tzdriver_new/tc_ns_client.h 2023-09-05 13:59:26.864000000 +0800
+@@ -209,4 +209,7 @@
+ #endif
+ #define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info)
++#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG \
++ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int)
++
+ #endif
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/tc_ns_log.h ./itrustee_tzdriver_new/tc_ns_log.h
+--- ./itrustee_tzdriver/tc_ns_log.h 2023-08-03 17:22:25.912000000 +0800
++++ ./itrustee_tzdriver_new/tc_ns_log.h 2023-09-05 13:59:26.864000000 +0800
+@@ -32,7 +32,7 @@
+ };
+ #define MOD_TEE "tzdriver"
+
+-#define TEE_LOG_MASK TZ_DEBUG_INFO
++#define TEE_LOG_MASK TZ_DEBUG_WARN
+
+ #define tlogv(fmt, args...) \
+ do { \
+diff -Naur '--exclude=.git' ./itrustee_tzdriver/teek_ns_client.h ./itrustee_tzdriver_new/teek_ns_client.h
+--- ./itrustee_tzdriver/teek_ns_client.h 2023-08-03 17:22:25.912000000 +0800
++++ ./itrustee_tzdriver_new/teek_ns_client.h 2023-09-05 13:59:26.860000000 +0800
+@@ -134,6 +134,8 @@
+ #ifdef CONFIG_TEE_TELEPORT_SUPPORT
+ bool portal_enabled;
+ #endif
++ uint32_t vmpid;
++ bool isVM;
+ };
+
+ union tc_ns_parameter {
+@@ -253,3 +255,4 @@
+ };
+
+ #endif
++
diff --git a/trustzone-awared-vm/host/vtzb_proxy/Makefile b/trustzone-awared-vm/host/vtzb_proxy/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e73c794fbcc2ca1a427536fed78e1b7e936cc270
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/Makefile
@@ -0,0 +1,33 @@
+TARGET_APP := vtzb_proxy
+LIBC_SEC := libboundscheck
+TARGET_LIBSEC := libboundscheck.so
+
+all: $(TARGET_LIBSEC) $(TARGET_APP)
+ @cd $(LIBC_SEC) && $(MAKE) clean
+
+$(TARGET_LIBSEC):
+ @echo "compile libboundscheck ..."
+ @$(MAKE) -C $(LIBC_SEC)
+ sudo cp -rf $(LIBC_SEC)/lib/libboundscheck.so /usr/lib64
+ @echo "compile libboundscheck done"
+
+APP_CFLAGS += -DSECURITY_AUTH_ENHANCE
+APP_CFLAGS += -Ilibboundscheck/include
+APP_CFLAGS += -Iinclude -Iinclude/cloud
+APP_CFLAGS += -Werror -Wall -Wextra -fstack-protector-all -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie -D_FORTIFY_SOURCE=2 -O2
+APP_LDFLAGS += -lboundscheck -Llibboundscheck/lib -lpthread
+
+APP_SOURCES := ./vtzb_proxy.c \
+ ./thread_pool.c \
+ ./virt.c
+
+APP_OBJECTS := $(APP_SOURCES:.c=.o)
+
+$(TARGET_APP): $(TARGET_LIBSEC) $(APP_SOURCES)
+ @echo "compile vtzb_proxy ..."
+ @$(CC) $(APP_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS)
+ @echo "compile vtzb_proxy done"
+
+clean:
+ @cd $(LIBC_SEC) && $(MAKE) clean
+ @rm -rf vtzb_proxy
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_client_log.h b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_client_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..59681ecdb2109e3f6001b800e5c7acb436abf6ce
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_client_log.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * iTrustee licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef TEE_CLIENT_LOG_H
+#define TEE_CLIENT_LOG_H
+
+#include
+
+#ifdef TEEC_DEBUG
+#define TEEC_Debug(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__);
+#else
+#define TEEC_Debug(...)
+#endif
+
+#define TEEC_Error(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__);
+
+#endif
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_session_pool.h b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_session_pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..5812698b70756c576d5da81f314d742ddb3e9400
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/cloud/tee_session_pool.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * iTrustee licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef _TEE_SESSION_POOL_H_
+#define _TEE_SESSION_POOL_H_
+
+#include
+#include "tee_client_api.h"
+
+struct SessionInfo {
+ TEEC_Session session;
+ bool isDead;
+};
+
+struct SessionPool {
+ TEEC_Context *context; /* context owner */
+ TEEC_UUID uuid;
+ uint32_t poolSize; /* expected count of sessions to open */
+ struct SessionInfo *sessionsInfo;
+ uint32_t opened; /* counf of sessions opend successfully */
+ uint32_t inuse; /* count of sessions in using */
+ sem_t keys; /* keys value equal opend - inuse */
+ uint8_t *usage; /* a bitmap mark session in-use */
+ uint32_t usageSize; /* bitmap size in bytes */
+ pthread_mutex_t usageLock;
+};
+
+TEEC_Result TEEC_SessionPoolCreate(TEEC_Context *context, const TEEC_UUID *destination,
+ struct SessionPool **sessionPool, uint32_t poolSize);
+TEEC_Result TEEC_SessionPoolInvoke(struct SessionPool *sessionPool, uint32_t commandID,
+ TEEC_Operation *operation, uint32_t *returnOrigin);
+void TEEC_SessionPoolDestroy(struct SessionPool *sessionPool);
+void TEEC_SessionPoolQuery(struct SessionPool *sessionPool, uint32_t *size,
+ uint32_t *opened, uint32_t *inuse, bool showBitmap);
+
+#endif
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tc_ns_client.h b/trustzone-awared-vm/host/vtzb_proxy/include/tc_ns_client.h
new file mode 100644
index 0000000000000000000000000000000000000000..24e2cd6a582deab75332e477c8ee87ee328c4ac0
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tc_ns_client.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
+ * Licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef _TC_NS_CLIENT_H_
+#define _TC_NS_CLIENT_H_
+#include "tee_client_type.h"
+#define TC_DEBUG
+
+#define INVALID_TYPE 0x00
+#define TEECD_CONNECT 0x01
+#ifndef ZERO_SIZE_PTR
+#define ZERO_SIZE_PTR ((void *)16)
+#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR)
+#endif
+
+#define UUID_SIZE 16
+
+#define TC_NS_CLIENT_IOC_MAGIC 't'
+#define TC_NS_CLIENT_DEV "tc_ns_client"
+#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client"
+#define TC_TEECD_PRIVATE_DEV_NAME "/dev/tc_private"
+#define TC_NS_CVM_DEV_NAME "/dev/tc_ns_cvm"
+
+enum ConnectCmd {
+ GET_FD,
+ GET_TEEVERSION,
+ SET_SYS_XML,
+ GET_TEECD_VERSION,
+};
+
+typedef struct {
+ unsigned int method;
+ unsigned int mdata;
+} TC_NS_ClientLogin;
+
+typedef union {
+ struct {
+ unsigned int buffer;
+ unsigned int buffer_h_addr;
+ unsigned int offset;
+ unsigned int h_offset;
+ unsigned int size_addr;
+ unsigned int size_h_addr;
+ } memref;
+ struct {
+ unsigned int a_addr;
+ unsigned int a_h_addr;
+ unsigned int b_addr;
+ unsigned int b_h_addr;
+ } value;
+} TC_NS_ClientParam;
+
+typedef struct {
+ unsigned int code;
+ unsigned int origin;
+} TC_NS_ClientReturn;
+
+typedef struct {
+ unsigned char uuid[UUID_SIZE];
+ unsigned int session_id;
+ unsigned int cmd_id;
+ TC_NS_ClientReturn returns;
+ TC_NS_ClientLogin login;
+ TC_NS_ClientParam params[TEEC_PARAM_NUM];
+ unsigned int paramTypes;
+ bool started;
+ unsigned int callingPid;
+ unsigned int file_size;
+ union {
+ char *file_buffer;
+ struct {
+ uint32_t file_addr;
+ uint32_t file_h_addr;
+ } memref;
+ };
+} TC_NS_ClientContext;
+
+typedef struct {
+ uint32_t seconds;
+ uint32_t millis;
+} TC_NS_Time;
+
+typedef struct {
+ uint16_t tzdriver_version_major;
+ uint16_t tzdriver_version_minor;
+ uint32_t reserved[15];
+} TC_NS_TEE_Info;
+
+enum SecFileType {
+ LOAD_TA = 0,
+ LOAD_SERVICE,
+ LOAD_LIB,
+ LOAD_DYNAMIC_DRV,
+ LOAD_PATCH,
+ LOAD_TYPE_MAX
+};
+
+struct SecFileInfo {
+ enum SecFileType fileType;
+ uint32_t fileSize;
+ int32_t secLoadErr;
+};
+
+struct SecLoadIoctlStruct {
+ struct SecFileInfo secFileInfo;
+ TEEC_UUID uuid;
+ union {
+ char *fileBuffer;
+ struct {
+ uint32_t file_addr;
+ uint32_t file_h_addr;
+ } memref;
+ };
+}__attribute__((packed));
+
+struct AgentIoctlArgs {
+ uint32_t id;
+ uint32_t bufferSize;
+ union {
+ void *buffer;
+ unsigned long long addr;
+ };
+};
+
+#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, TC_NS_ClientContext)
+#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, TC_NS_ClientContext)
+#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, TC_NS_ClientContext)
+#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int)
+#define TC_NS_CLIENT_IOCTL_WAIT_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int)
+#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int)
+#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct AgentIoctlArgs)
+#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int)
+#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct SecLoadIoctlStruct)
+#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, TC_NS_ClientContext)
+#define TC_NS_CLIENT_IOCTL_LOAD_APP_EXCEPT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 11, unsigned int)
+#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, TC_NS_ClientContext)
+#define TC_NS_CLIENT_IOCTL_LOGIN _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int)
+#define TC_NS_CLIENT_IOCTL_TST_CMD_REQ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 15, int)
+#define TC_NS_CLIENT_IOCTL_TUI_EVENT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int)
+#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, TC_NS_Time)
+#define TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int)
+#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int)
+#define TC_NS_CLIENT_IOCTL_LATEINIT _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int)
+#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int)
+#ifdef CONFIG_CMS_SIGNATURE
+#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct TC_NS_ClientCrl)
+#endif
+#ifdef CONFIG_TEE_TELEPORT_SUPPORT
+#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct AgentIoctlArgs)
+#define TC_NS_CLIENT_IOCTL_PORTAL_WORK _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct AgentIoctlArgs)
+#endif
+#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, TC_NS_TEE_Info)
+#define TC_NS_CLIENT_IOCTL_SET_VM_FLAG _IOWR(TC_NS_CLIENT_IOC_MAGIC, 27, int)
+TEEC_Result TEEC_CheckOperation(const TEEC_Operation *operation);
+#endif
+
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_api.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..d68997907464646b715802c560da1962b9139867
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_api.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved.
+ * iTrustee licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef _TEE_CLIENT_API_H_
+#define _TEE_CLIENT_API_H_
+
+#ifndef LOG_TAG
+#define LOG_TAG NULL
+#endif
+
+#include
+#include "tee_client_type.h"
+#include "tee_client_ext_api.h"
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define S_VAR_NOT_USED(variable) do { (void)(variable); } while (0)
+
+#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \
+ ((param3Type) << 12 | (param2Type) << 8 | (param1Type) << 4 | (param0Type))
+
+#define TEEC_PARAM_TYPE_GET(paramTypes, index) \
+ (((paramTypes) >> (4*(index))) & 0x0F)
+
+#define TEEC_VALUE_UNDEF 0xFFFFFFFF
+
+/*
+ * initializes a new TEE Context, forming a connection between this Client Application and the TEE
+ *
+ * @param name [IN] TEE name (unused)
+ * @param context [OUT] pointer to TEEC_Context to be initialized
+ *
+ * @return TEEC_SUCCESS operation success
+ * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter
+ * @return TEEC_ERROR_GENERIC system error unhandled
+ */
+TEEC_Result TEEC_InitializeContext(
+ const char *name,
+ TEEC_Context *context);
+
+/*
+ * finalizes an initialized TEE Context, closing the connection between the Client Application and the TEE
+ *
+ * @param context [IN/OUT] pointer to TEEC_Context initialized by TEEC_InitializeContext
+ *
+ * @return void
+ */
+void TEEC_FinalizeContext(
+ TEEC_Context *context);
+
+/*
+ * opens a new Session between the Client Application and the specified Trusted Application
+ *
+ * @param context [IN/OUT] a pointer to an initialized TEE Context
+ * @param session [OUT] a pointer to a Session structure to be opened
+ * @param destination [IN] a pointer to a structure containing the UUID of the destination Trusted Application
+ * @param connectionMethod [IN] the method of connection to use
+ * @param connectionData [IN] any necessary data required to support the connection method
+ * @param operation [IN/OUT] a pointer to an Operation containing a set of Parameters to exchange with the
+ * Trusted Application
+ * @param returnOrigin [OUT] a pointer to a variable which will contain the return origin, This field may be NULL
+ * if the return origin is not needed
+ *
+ * @return TEEC_SUCCESS operation success
+ * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or session or destination is NULL
+ * @return TEEC_ERROR_ACCESS_DENIED client Application's connection request is denied
+ * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use
+ * @return TEEC_ERROR_TRUSTED_APP_LOAD_ERROR load Trusted Application failed
+ * @return others refer TEEC_ReturnCode
+ */
+TEEC_Result TEEC_OpenSession(
+ TEEC_Context *context,
+ TEEC_Session *session,
+ const TEEC_UUID *destination,
+ uint32_t connectionMethod,
+ const void *connectionData,
+ TEEC_Operation *operation,
+ uint32_t *returnOrigin);
+
+/*
+ * closes a Session which has been opened with a Trusted Application
+ *
+ * @param session [IN/OUT] pointer to a session to be closed
+ *
+ * @return void
+ */
+void TEEC_CloseSession(
+ TEEC_Session *session);
+
+/*
+ * invokes a Command within the specified Session
+ *
+ * @param session [IN/OUT] the open Session in which the command will be invoked
+ * @param commandID [IN] the identifier of the Command within the Trusted Application to invoke
+ * @param operation [IN/OUT] a pointer to a Client Application initialized TEEC_Operation structure
+ * @param returnOrigin [OUT] a pointer to a variable which will contain the return origin
+ *
+ * @return TEEC_SUCCESS operation success
+ * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, session is NULL or operation data invalid
+ * @return TEEC_ERROR_ACCESS_DENIED invoke command operation is denied
+ * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use
+ * @return others refer TEEC_ReturnCode
+ */
+TEEC_Result TEEC_InvokeCommand(
+ TEEC_Session *session,
+ uint32_t commandID,
+ TEEC_Operation *operation,
+ uint32_t *returnOrigin);
+
+/*
+ * registers a block of existing Client Application memory as a block of Shared Memory within
+ * the scope of the specified TEE Context, in accordance with the parameters which have been set by the
+ * Client Application inside the sharedMem structure (don't support 0 size data)
+ *
+ * @param context [IN/OUT] a pointer to an initialized TEE Context
+ * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to register
+ *
+ * @return TEEC_SUCCESS operation success
+ * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL
+ */
+TEEC_Result TEEC_RegisterSharedMemory(
+ TEEC_Context *context,
+ TEEC_SharedMemory *sharedMem);
+
+/*
+ * allocates a new block of memory as a block of Shared Memory within the scope of the specified TEE Context
+ * size of sharedMem should not be 0
+ *
+ * @param context [IN/OUT] a pointer to an initialized TEE Context
+ * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to allocate
+ *
+ * @return TEEC_SUCCESS operation success
+ * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL
+ * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use
+ */
+TEEC_Result TEEC_AllocateSharedMemory(
+ TEEC_Context *context,
+ TEEC_SharedMemory *sharedMem);
+
+/*
+ * deregisters or deallocates a previously initialized block of Shared Memory
+ * if memory is allocated by TEEC_AllocateSharedMemory, system will free this memory
+ * if memory is registered by TEEC_RegisterSharedMemory, system will not free this memory
+ *
+ * @param sharedMem [IN/OUT] a pointer to a valid Shared Memory structure
+ *
+ * @return void
+ */
+void TEEC_ReleaseSharedMemory(
+ TEEC_SharedMemory *sharedMem);
+
+/*
+ * requests the cancellation of a pending open Session operation or a Command invocation operation
+ * this operation is not supported currently
+ *
+ * @param operation [IN/OUT] a pointer to a Client Application instantiated Operation structure
+ *
+ * @return void
+ */
+void TEEC_RequestCancellation(
+ TEEC_Operation *operation);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_constants.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_constants.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a7e31f678d2c9ad31a2ac44d9b4e7cc58b6700a
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_constants.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved.
+ * Licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef _TEE_CLIENT_CONSTANTS_H_
+#define _TEE_CLIENT_CONSTANTS_H_
+
+enum TEEC_ReturnCode {
+ TEEC_SUCCESS = 0x0, /* success */
+ TEEC_ERROR_INVALID_CMD, /* invalid command */
+ TEEC_ERROR_SERVICE_NOT_EXIST, /* target service is not exist */
+ TEEC_ERROR_SESSION_NOT_EXIST, /* session between client and service is not exist */
+ TEEC_ERROR_SESSION_MAXIMUM, /* exceed max num of sessions */
+ TEEC_ERROR_REGISTER_EXIST_SERVICE, /* cannot register the service which already exist */
+ TEEC_ERROR_TAGET_DEAD_FATAL, /* system error occurs in TEE */
+ TEEC_ERROR_READ_DATA, /* failed to read data in file */
+ TEEC_ERROR_WRITE_DATA, /* failed to write data to file */
+ TEEC_ERROR_TRUNCATE_OBJECT, /* data is truncated */
+ TEEC_ERROR_SEEK_DATA, /* failed to seek data in file */
+ TEEC_ERROR_FSYNC_DATA, /* failed to sync data in file */
+ TEEC_ERROR_RENAME_OBJECT, /* failed to rename file */
+ TEEC_ERROR_TRUSTED_APP_LOAD_ERROR, /* failed to load Trusted Application */
+ TEEC_ERROR_GENERIC = 0xFFFF0000, /* generic error occurs */
+ TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001, /* permission check failed, in initilize context or
+ open session or invoke commnad */
+ TEEC_ERROR_CANCEL = 0xFFFF0002, /* operation is already canceled */
+ TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003, /* confilct occurs in concurrent access to data,
+ error occurs in file operaions generally */
+ TEEC_ERROR_EXCESS_DATA = 0xFFFF0004, /* exceed max data to be handled by system */
+ TEEC_ERROR_BAD_FORMAT = 0xFFFF0005, /* data format is invalid, Trusted Application cannot
+ handle it */
+ TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006, /* invalid parameters */
+ TEEC_ERROR_BAD_STATE = 0xFFFF0007, /* operation failed in current state, when try to access
+ storage without initilize storage service */
+ TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008, /* cannot find target item */
+ TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009, /* request operation is not implemented */
+ TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A, /* request operation is not supported */
+ TEEC_ERROR_NO_DATA = 0xFFFF000B, /* no data present for current operation */
+ TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C, /* system resource if out of use */
+ TEEC_ERROR_BUSY = 0xFFFF000D, /* system is too busy to handle current operation */
+ TEEC_ERROR_COMMUNICATION = 0xFFFF000E, /* error occurs when client try to communicate
+ with Trusted Application */
+ TEEC_ERROR_SECURITY = 0xFFFF000F, /* security error occurs */
+ TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010, /* out buffer is not enough for current request */
+ TEEC_ERROR_MAC_INVALID = 0xFFFF3071, /* MAC value check failed */
+ TEEC_ERROR_TARGET_DEAD = 0xFFFF3024, /* Trusted Application is crashed */
+ TEEC_FAIL = 0xFFFF5002, /* common error */
+ TEEC_ERROR_EXTERNAL_CANCEL = 0xFFFF0011, /* used by adapt only, event caused User Interface operation aborted */
+ TEEC_ERROR_OVERFLOW = 0xFFFF300F, /* used by adapt only */
+ TEEC_ERROR_STORAGE_NO_SPACE = 0xFFFF3041, /* used by adapt only */
+ TEEC_ERROR_SIGNATURE_INVALID = 0xFFFF3072, /* used by adapt only */
+ TEEC_ERROR_TIME_NOT_SET = 0xFFFF5000, /* used by adapt only */
+ TEEC_ERROR_TIME_NEEDS_RESET = 0xFFFF5001, /* used by adapt only */
+ TEEC_ERROR_IPC_OVERFLOW = 0xFFFF9114 /* ipc overflow */
+};
+
+enum TEEC_ReturnCodeOrigin {
+ TEEC_ORIGIN_API = 0x1, /* error occurs in handling client API */
+ TEEC_ORIGIN_COMMS = 0x2, /* error occurs in communicating between REE and TEE */
+ TEEC_ORIGIN_TEE = 0x3, /* error occurs in TEE */
+ TEEC_ORIGIN_TRUSTED_APP = 0x4, /* error occurs in Trusted Application */
+};
+
+enum TEEC_SharedMemCtl {
+ TEEC_MEM_INPUT = 0x1, /* input type of memroy */
+ TEEC_MEM_OUTPUT = 0x2, /* output type of memory */
+ TEEC_MEM_INOUT = 0x3, /* memory is used as both input and output */
+ TEEC_MEM_SHARED_INOUT = 0x4, /* no copy shared memory */
+};
+
+enum TEEC_ParamType {
+ TEEC_NONE = 0x0, /* unused parameter */
+ TEEC_VALUE_INPUT = 0x01, /* input type of value, refer TEEC_Value */
+ TEEC_VALUE_OUTPUT = 0x02, /* output type of value, refer TEEC_Value */
+ TEEC_VALUE_INOUT = 0x03, /* value is used as both input and output, refer TEEC_Value */
+ TEEC_MEMREF_TEMP_INPUT = 0x05, /* input type of temp memory reference, refer TEEC_TempMemoryReference */
+ TEEC_MEMREF_TEMP_OUTPUT = 0x06, /* output type of temp memory reference, refer TEEC_TempMemoryReference */
+ TEEC_MEMREF_TEMP_INOUT = 0x07, /* temp memory reference used as both input and output,
+ refer TEEC_TempMemoryReference */
+ TEEC_ION_INPUT = 0x08, /* input type of icon memory reference, refer TEEC_IonReference */
+ TEEC_ION_SGLIST_INPUT = 0x09, /* input type of ion memory block reference, refer TEEC_IonSglistReference */
+ TEEC_MEMREF_SHARED_INOUT = 0x0a, /* no copy mem */
+ TEEC_MEMREF_WHOLE = 0xc, /* use whole memory block, refer TEEC_RegisteredMemoryReference */
+ TEEC_MEMREF_PARTIAL_INPUT = 0xd, /* input type of memory reference, refer TEEC_RegisteredMemoryReference */
+ TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, /* output type of memory reference, refer TEEC_RegisteredMemoryReference */
+ TEEC_MEMREF_PARTIAL_INOUT = 0xf /* memory reference used as both input and output,
+ refer TEEC_RegisteredMemoryReference */
+};
+
+/****************************************************
+ * Session Login Methods
+ ****************************************************/
+enum TEEC_LoginMethod {
+ TEEC_LOGIN_PUBLIC = 0x0, /* no Login data is provided */
+ TEEC_LOGIN_USER, /* Login data about the user running the
+ Client Application process is provided */
+ TEEC_LOGIN_GROUP, /* Login data about the group running
+ the Client Application process is provided */
+ TEEC_LOGIN_APPLICATION = 0x4, /* Login data about the running Client
+ Application itself is provided */
+ TEEC_LOGIN_USER_APPLICATION = 0x5, /* Login data about the user running the
+ Client Application and about the
+ Client Application itself is provided */
+ TEEC_LOGIN_GROUP_APPLICATION = 0x6, /* Login data about the group running
+ the Client Application and about the
+ Client Application itself is provided */
+ TEEC_LOGIN_IDENTIFY = 0x7, /* Login data is provided by REE system */
+};
+enum TST_CMD_ID {
+ TST_CMD_ID_01 = 1,
+ TST_CMD_ID_02,
+ TST_CMD_ID_03,
+ TST_CMD_ID_04,
+ TST_CMD_ID_05
+};
+
+#define TEEC_PARAM_NUM 4 /* teec param max number */
+#endif
+
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_list.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_list.h
new file mode 100644
index 0000000000000000000000000000000000000000..d14656c051631001ed5e82140489ae7614d36ee3
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_list.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2021. All rights reserved.
+ * iTrustee licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef TEE_CLIENT_LIST_H
+#define TEE_CLIENT_LIST_H
+
+struct ListNode {
+ struct ListNode *next; /* point to next node */
+ struct ListNode *prev; /* point to prev node */
+};
+
+#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member))
+#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member))
+
+#define LIST_DECLARE(name) \
+ struct ListNode name = { \
+ .next = &name, \
+ .prev = &name, \
+ }
+
+static inline void ListInit(struct ListNode *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+#define LIST_HEAD(list) ((list)->next)
+#define LIST_TAIL(list) ((list)->prev)
+#define LIST_EMPTY(list) ((list) == (list)->next)
+
+static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry)
+{
+ list->next->prev = entry;
+ entry->next = list->next;
+ entry->prev = list;
+ list->next = entry;
+}
+
+static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry)
+{
+ entry->next = list;
+ entry->prev = list->prev;
+ list->prev->next = entry;
+ list->prev = entry;
+}
+
+static inline void ListRemoveEntry(struct ListNode *entry)
+{
+ entry->prev->next = entry->next;
+ entry->next->prev = entry->prev;
+}
+
+static inline struct ListNode *ListRemoveHead(struct ListNode *list)
+{
+ struct ListNode *entry = NULL;
+ if (!LIST_EMPTY(list)) {
+ entry = list->next;
+ ListRemoveEntry(entry);
+ }
+ return entry;
+}
+
+static inline struct ListNode *ListRemoveTail(struct ListNode *list)
+{
+ struct ListNode *entry = NULL;
+ if (!LIST_EMPTY(list)) {
+ entry = list->prev;
+ ListRemoveEntry(entry);
+ }
+ return entry;
+}
+
+#define LIST_ENTRY(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+#define LIST_FOR_EACH(pos, list) \
+ for (pos = (list)->next; pos != (list); pos = pos->next)
+
+#define LIST_FOR_EACH_SAFE(pos, n, list) \
+ for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next)
+
+#define LIST_FOR_EACH_ENTRY(pos, list, member) \
+ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \
+ pos = LIST_ENTRY(pos->member.next, typeof(*pos), member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \
+ for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \
+ member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member))
+
+#endif
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_type.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_type.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ff7692b77c62efa87419f27535c60f40a40e38c
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tee_client_type.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2013-2022. All rights reserved.
+ * Licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef _TEE_CLIENT_TYPE_H_
+#define _TEE_CLIENT_TYPE_H_
+
+#include
+#include
+#include
+#include
+#include
+#include "tee_client_list.h"
+#include "tee_client_constants.h"
+
+typedef enum TEEC_ReturnCode TEEC_Result;
+
+typedef struct {
+ uint32_t timeLow;
+ uint16_t timeMid;
+ uint16_t timeHiAndVersion;
+ uint8_t clockSeqAndNode[8];
+} TEEC_UUID;
+
+typedef struct {
+ int32_t fd;
+ uint8_t *ta_path;
+ struct ListNode session_list;
+ struct ListNode shrd_mem_list;
+ union {
+ struct {
+ void *buffer;
+ sem_t buffer_barrier;
+ } share_buffer;
+ uint64_t imp; /* for adapt */
+ };
+} TEEC_Context;
+
+typedef struct {
+ uint32_t session_id;
+ TEEC_UUID service_id;
+ uint32_t ops_cnt;
+ union {
+ struct ListNode head;
+ uint64_t imp; /* for adapt */
+ };
+ TEEC_Context *context;
+} TEEC_Session;
+
+typedef struct {
+ void *buffer;
+ uint32_t size;
+ uint32_t flags; /* reference to TEEC_SharedMemCtl */
+ uint32_t ops_cnt;
+ bool is_allocated; /* identify whether the memory is registered or allocated */
+ union {
+ struct ListNode head;
+ void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */
+ };
+ TEEC_Context *context;
+} TEEC_SharedMemory;
+
+/*
+ * the corresponding param types are
+ * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT
+ */
+typedef struct {
+ void *buffer;
+ uint32_t size;
+} TEEC_TempMemoryReference;
+
+/*
+ * the corresponding param types are
+ * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT
+ * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT
+ */
+typedef struct {
+ TEEC_SharedMemory *parent;
+ uint32_t size;
+ uint32_t offset;
+} TEEC_RegisteredMemoryReference;
+
+/*
+ * the corresponding param types are
+ * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT
+ */
+typedef struct {
+ uint32_t a;
+ uint32_t b;
+} TEEC_Value;
+
+typedef struct {
+ int ion_share_fd;
+ uint32_t ion_size;
+} TEEC_IonReference;
+
+typedef union {
+ TEEC_TempMemoryReference tmpref;
+ TEEC_RegisteredMemoryReference memref;
+ TEEC_Value value;
+ TEEC_IonReference ionref;
+} TEEC_Parameter;
+
+typedef struct {
+ uint32_t event_type; /* Tui event type */
+ uint32_t value; /* return value, is keycode if tui event is getKeycode */
+ uint32_t notch; /* notch size of the screen for tui */
+ uint32_t width; /* width of foldable screen */
+ uint32_t height; /* height of foldable screen */
+ uint32_t fold_state; /* state of foldable screen */
+ uint32_t display_state; /* one state of folded state */
+ uint32_t phy_width; /* real width of the mobile */
+ uint32_t phy_height; /* real height of the mobile */
+} TEEC_TUI_Parameter;
+
+typedef struct {
+ uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */
+ uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */
+ TEEC_Parameter params[TEEC_PARAM_NUM];
+ TEEC_Session *session;
+ bool cancel_flag;
+} TEEC_Operation;
+
+#endif
+
diff --git a/trustzone-awared-vm/host/vtzb_proxy/include/tee_sys_log.h b/trustzone-awared-vm/host/vtzb_proxy/include/tee_sys_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fa0c3deaa85c4f994bb149a742945a59f2684dc
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/include/tee_sys_log.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * iTrustee licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#ifndef TEEC_SYS_LOG_H
+#define TEEC_SYS_LOG_H
+
+#include
+
+// #define TEE_LOG_MASK TZ_LOG_ERROR
+#define TEE_LOG_MASK TZ_LOG_VERBOSE
+
+#define TZ_LOG_VERBOSE 0
+#define TZ_LOG_INFO 1
+#define TZ_LOG_WARN 2
+#define TZ_LOG_DEBUG 3
+#define TZ_LOG_ERROR 4
+
+#define tlogv(...) \
+ do { \
+ if (TZ_LOG_VERBOSE == TEE_LOG_MASK) \
+ syslog(LOG_USER | LOG_NOTICE, __VA_ARGS__); \
+ } while (0)
+
+#define tlogd(...) \
+ do { \
+ if (TZ_LOG_DEBUG >= TEE_LOG_MASK) \
+ syslog(LOG_USER | LOG_DEBUG, __VA_ARGS__); \
+ } while (0)
+
+#define tlogi(...) \
+ do { \
+ if (TZ_LOG_INFO >= TEE_LOG_MASK) \
+ syslog(LOG_USER | LOG_INFO, __VA_ARGS__); \
+ } while (0)
+
+#define tlogw(...) \
+ do { \
+ if (TZ_LOG_WARN >= TEE_LOG_MASK) \
+ syslog(LOG_USER | LOG_WARNING, __VA_ARGS__); \
+ } while (0)
+
+#define tloge(...) \
+ do { \
+ if (TZ_LOG_ERROR >= TEE_LOG_MASK) \
+ syslog(LOG_USER | LOG_ERR, __VA_ARGS__); \
+ } while (0)
+
+#endif
+
diff --git a/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..86a6becff15081f6019071cbc403e2fff10c2155
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.c
@@ -0,0 +1,124 @@
+#include
+#include
+#include
+#include "thread_pool.h"
+
+// 初始化线程池
+void thread_pool_init(ThreadPool* pool)
+{
+ pool->task_count = 0;
+ pool->front = pool->rear = 0;
+ pool->destroying = 0;
+ pthread_mutex_init(&pool->mutex, NULL);
+ pthread_cond_init(&pool->cond, NULL);
+
+ for (int i = 0; i < THREAD_POOL_SIZE; i++) {
+ pthread_create(&pool->threads[i], NULL, thread_func, pool);
+ }
+}
+
+// 线程函数
+void* thread_func(void* arg)
+{
+ ThreadPool* pool = (ThreadPool*)arg;
+
+ while (1) {
+ pthread_mutex_lock(&pool->mutex);
+
+ // 等待任务队列非空
+ while (pool->task_count == 0 && !pool->destroying) {
+ pthread_cond_wait(&pool->cond, &pool->mutex);
+ }
+
+ // 如果正在销毁线程池,则退出线程
+ if (pool->destroying) {
+ pthread_mutex_unlock(&pool->mutex);
+ break;
+ }
+
+ // 取出任务并执行
+ Task task = pool->task_queue[pool->front];
+ pool->front = (pool->front + 1) % TASK_QUEUE_SIZE;
+ pool->task_count--;
+ pthread_mutex_unlock(&pool->mutex);
+
+ task.task_func(task.arg);
+ }
+
+ return NULL;
+}
+
+// 提交任务到线程池
+void thread_pool_submit(ThreadPool* pool, void* (*task_func)(void*), void* arg)
+{
+ pthread_mutex_lock(&pool->mutex);
+
+ // 等待任务队列非满
+ while (pool->task_count == TASK_QUEUE_SIZE && !pool->destroying) {
+ pthread_cond_wait(&pool->cond, &pool->mutex);
+ }
+
+ // 如果正在销毁线程池,则不再接收新任务
+ if (pool->destroying) {
+ pthread_mutex_unlock(&pool->mutex);
+ return;
+ }
+
+ // 添加任务到队列
+ pool->task_queue[pool->rear].task_func = task_func;
+ pool->task_queue[pool->rear].arg = arg;
+ pool->rear = (pool->rear + 1) % TASK_QUEUE_SIZE;
+ pool->task_count++;
+ // 通知等待中的线程有新任务
+ pthread_cond_signal(&pool->cond);
+
+ pthread_mutex_unlock(&pool->mutex);
+}
+
+// 销毁线程池
+void thread_pool_destroy(ThreadPool* pool)
+{
+ // 停止接收新的任务
+ pthread_mutex_lock(&pool->mutex);
+ pool->destroying = 1; // 设置标志,表示正在销毁线程池
+ pthread_mutex_unlock(&pool->mutex);
+
+ // 通知所有等待中的线程有新任务(用于唤醒正在等待任务的线程,让它们检查销毁标志)
+ pthread_cond_broadcast(&pool->cond);
+
+ // 等待所有线程执行完成
+ for (int i = 0; i < THREAD_POOL_SIZE; i++) {
+ pthread_join(pool->threads[i], NULL);
+ }
+
+ // 销毁互斥锁和条件变量
+ pthread_mutex_destroy(&pool->mutex);
+ pthread_cond_destroy(&pool->cond);
+}
+
+/*
+// 示例任务函数
+void task_function(void* arg) {
+ int task_arg = *((int*)arg);
+ printf("Task argument: %d\n", task_arg);
+}
+
+// 主函数
+int main() {
+ ThreadPool pool;
+ thread_pool_init(&pool);
+
+ int tasks[10];
+ for (int i = 0; i < 10; i++) {
+ tasks[i] = i + 1;
+ thread_pool_submit(&pool, task_function, &tasks[i]);
+ }
+
+ // 等待一段时间,模拟其他工作
+ sleep(3);
+
+ // 销毁线程池
+ thread_pool_destroy(&pool);
+
+ return 0;
+}*/
diff --git a/trustzone-awared-vm/host/vtzb_proxy/thread_pool.h b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..96ed32f22fe16695bff997e24edf0e926fda182e
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/thread_pool.h
@@ -0,0 +1,33 @@
+#ifndef __THREAD_POLL_H__
+#define __THREAD_POLL_H__
+
+#include
+#include
+#include
+
+#define THREAD_POOL_SIZE 5
+#define TASK_QUEUE_SIZE 10
+
+// 定义任务结构
+typedef struct {
+ void* (*task_func)(void*); // 任务函数指针
+ void* arg; // 任务参数
+} Task;
+
+// 定义线程池结构
+typedef struct {
+ pthread_t threads[THREAD_POOL_SIZE]; // 线程数组
+ Task task_queue[TASK_QUEUE_SIZE]; // 任务队列
+ int task_count; // 任务队列中任务数量
+ int front; // 队列头索引
+ int rear; // 队列尾索引
+ int destroying; // 销毁标志
+ pthread_mutex_t mutex; // 互斥锁
+ pthread_cond_t cond; // 条件变量
+} ThreadPool;
+
+void thread_pool_init(ThreadPool* pool);
+void thread_pool_destroy(ThreadPool* pool);
+void* thread_func(void* arg);
+void thread_pool_submit(ThreadPool* pool, void* (*task_func)(void*), void* arg);
+#endif
diff --git a/trustzone-awared-vm/host/vtzb_proxy/virt.c b/trustzone-awared-vm/host/vtzb_proxy/virt.c
new file mode 100644
index 0000000000000000000000000000000000000000..2521d4cb8d19e6604a9d071cbf39b8d2949b47d9
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/virt.c
@@ -0,0 +1,92 @@
+#include "virt.h"
+
+// static int safepoll(struct pollfd *fds, nfds_t nfds, int timeout)
+int safepoll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+ int ret;
+
+ do {
+ // debug("Debug %s %s %d \n", __FILE__, __FUNCTION__, __LINE__);
+ ret = poll(fds, nfds, timeout);
+ // debug("Debug %s %s %d \n", __FILE__, __FUNCTION__, __LINE__);
+ // debug(" poll ret = %d, errno = %d \n", ret, errno);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret == -1)
+ ret = -errno;
+
+ return ret;
+}
+
+ssize_t safewrite(int fd, const void *buf, size_t count, bool eagain_ret)
+{
+ ssize_t ret;
+ size_t len;
+ int flags;
+ bool nonblock;
+
+ nonblock = false;
+ flags = fcntl(fd, F_GETFL);
+ if (flags > 0 && flags & O_NONBLOCK)
+ nonblock = true;
+
+ len = count;
+ while (len > 0) {
+ ret = write(fd, buf, len);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN) {
+ if (nonblock && eagain_ret) {
+ return -EAGAIN;
+ } else {
+ continue;
+ }
+ }
+ return -errno;
+ } else if (ret == 0) {
+ break;
+ } else {
+ buf += ret;
+ len -= ret;
+ }
+ }
+ return count - len;
+}
+
+ssize_t saferead(int fd, void *buf, size_t count, bool eagain_ret)
+{
+ size_t ret, len;
+ int flags;
+ bool nonblock;
+
+ nonblock = false;
+ flags = fcntl(fd, F_GETFL);
+ if (flags > 0 && flags & O_NONBLOCK)
+ nonblock = true;
+
+ len = count;
+ while (len > 0) {
+ ret = read(fd, buf, len);
+ if ((int)ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN) {
+ if (nonblock && eagain_ret) {
+ return -EAGAIN;
+ } else {
+ continue;
+ }
+ }
+ return -errno;
+ } else if (ret == 0) {
+ break;
+ } else {
+ buf += ret;
+ len -= ret;
+ }
+ }
+ return count - len;
+}
diff --git a/trustzone-awared-vm/host/vtzb_proxy/virt.h b/trustzone-awared-vm/host/vtzb_proxy/virt.h
new file mode 100644
index 0000000000000000000000000000000000000000..85913852e8ca9514388dcedcdcbeb7fb39bc9d3e
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/virt.h
@@ -0,0 +1,20 @@
+#ifndef VTZB_VIRT_H
+#define VTZB_VIRT_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+int safepoll(struct pollfd *fds, nfds_t nfds, int timeout);
+ssize_t safewrite(int fd, const void *buf, size_t count, bool eagain_ret);
+ssize_t saferead(int fd, void *buf, size_t count, bool eagain_ret);
+
+#endif // VTZB_VIRT_H
diff --git a/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.c b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.c
new file mode 100644
index 0000000000000000000000000000000000000000..8252359c60bb55051be9faf02bb3bd1ad08d0635
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.c
@@ -0,0 +1,1074 @@
+/*
+ */
+
+#include "vtzb_proxy.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include /* for mmap */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "securec.h"
+#include "tc_ns_client.h"
+#include "tee_client_list.h"
+#include "virt.h"
+#include "thread_pool.h"
+
+//#define DEBUG 1
+ThreadPool pool;
+LIST_DECLARE(g_shrd_mem_list);
+LIST_DECLARE(g_agent_buf_list);
+pthread_mutex_t g_mutex_shrd_mem = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t g_mutex_agent_buf = PTHREAD_MUTEX_INITIALIZER;
+
+double __get_us(struct timeval t)
+{
+ return (t.tv_sec * 1000000 + t.tv_usec);
+}
+
+#ifdef DEBUG
+void debug(const char* fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+#define PRINTF_SIZE 16
+void dump_buff(const char* buffer, size_t bufLen)
+{
+ size_t i;
+ if (buffer == NULL || bufLen == 0) {
+ return;
+ }
+ printf("--------------------------------------------------\n");
+ printf("bufLen = %d\n", (int)bufLen);
+ for (i = 0; i < bufLen; i++) {
+ if (i % PRINTF_SIZE == 0 && i != 0) {
+ printf("\n");
+ }
+ printf("%02x ", *(buffer + i));
+ }
+ printf("\n--------------------------------------------------\n");
+ return;
+}
+#else
+#define debug(fmt, ...) \
+ do { \
+ } while (0)
+
+#define dump_buff(buffer, bufLen) \
+ do { \
+ } while (0)
+#endif
+
+#define BUF_LENGTH 4080
+
+static unsigned int nr_failed;
+
+int connect_domsock_chardev(char* dev_path, int* sock)
+{
+ int ret;
+ ret = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ret == -1) {
+ tloge("execute socket() failed \n");
+ return -1;
+ }
+
+ *sock = ret;
+
+ struct sockaddr_un sock_addr;
+ sock_addr.sun_family = AF_UNIX;
+ memcpy_s(&sock_addr.sun_path, sizeof(sock_addr.sun_path), dev_path,
+ sizeof(sock_addr.sun_path));
+ ret = connect(*sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
+ if (ret < 0) {
+ tloge("connect domain socket %s failed \n", dev_path);
+ }
+
+ return ret;
+}
+
+////////////////////
+// static int g_fsFd = -1;
+// static struct SecStorageType *g_fsControl = NULL;
+#define TRANS_BUFF_SIZE (4 * 1024) /* agent transfer share buffer size */
+#define AGENT_FS_ID 0x46536673 /* FSfs */
+/*
+static int AgentInit(unsigned int id, void **control)
+{
+ int ret;
+ struct AgentIoctlArgs args = { 0 };
+
+ if (control == NULL) {
+ return -1;
+ }
+ int fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR);
+ if (fd < 0) {
+ debug("open tee client dev failed, fd is %d\n", fd);
+ return -1;
+ }
+
+ // register agent
+ args.id = id;
+ args.bufferSize = TRANS_BUFF_SIZE;
+ ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_REGISTER_AGENT, &args);
+ if (ret) {
+ (void)close(fd);
+ debug(" TC_NS_CLIENT_IOCTL_REGISTER_AGENT failed\n");
+ return -1;
+ }
+
+ *control = args.buffer;
+ return fd;
+}
+
+static int ProcessAgentInit()
+{
+ int ret = 0;
+ g_fsFd = AgentInit(AGENT_FS_ID, (void **)(&g_fsControl));
+ if (g_fsFd < 0) {
+ debug("fs agent init failed\n");
+ ret = -1;
+ } else {
+ //debug("<------------------ \n");
+ //debug("before TC_NS_CLIENT_IOCTL__EVENT\n");
+ //ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_WAIT_EVENT,
+AGENT_FS_ID);
+ //ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE,
+AGENT_FS_ID);
+ //debug("after TC_NS_CLIENT_IOCTL__EVENT, ret = %d\n", ret);
+ //debug("------------------> \n");
+ }
+ return ret;
+}
+
+
+void* fs_test(){
+ //(void)ProcessAgentInit();
+ int ret = ioctl(g_fsFd, (int32_t)TC_NS_CLIENT_IOCTL_WAIT_EVENT,
+AGENT_FS_ID); debug("after wait ret = %d\n", ret); ret = ioctl(g_fsFd,
+(int32_t)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, AGENT_FS_ID); debug("after rsp
+ret = %d\n",ret); return NULL;
+}
+*/
+
+/*
+void* serial_test() {
+ uint8_t ui8p_rd_buf[512];
+ struct pollfd pollfd[1];
+ char g_teeVersion[256U];
+ int i = 1000;
+ // int data = 1000;
+ int sock;
+ int ret = connect_domsock_chardev("/tmp/vm03_vtzb_sock1", &sock);
+ if (ret <0 ){
+ debug("open socket failed! \n");
+ return NULL;
+ }
+
+ pollfd[0].fd = sock;
+ pollfd[0].events = POLLIN;
+ while(i--){
+
+ // ret = write(sock, &data, sizeof(int));
+ // debug(" write to VM ,data = %d", data);
+ // data++;
+ // debug(" before poll \n");
+
+ ret = safepoll(pollfd, 1, -1);
+ //debug(" after poll \n");
+ if (ret == -1) {
+ debug("pollfd failed, ret = %d \n", ret);
+ return NULL;
+ }
+ if (ret == 0) {
+ debug("pollfd timeout \n");
+ continue;
+ }
+ if (pollfd[0].revents & POLLIN) {
+ ret = read(pollfd[0].fd, ui8p_rd_buf, 512);
+ if (*((uint32_t*)ui8p_rd_buf) == VTZF_TLOG_GET_VER) {
+ int fd = open("/dev/teelog", O_RDONLY);
+ if (fd < 0) {
+ tloge("open log device error\n");
+ return NULL;
+ }
+
+ tlogd("open dev success Fd=%d\n", fd);
+ ret = ioctl(fd, TEELOGGER_GET_VERSION, g_teeVersion);
+ if (ret != 0) {
+ tloge("get tee verison failed %d\n", ret);
+ }
+ g_teeVersion[255] = 0;
+ debug("tlog fd = %d \n",fd);
+ debug(" tver = %s \n ", g_teeVersion);
+ struct_vtzf_packet_rsp_tlog args_rsp;
+ args_rsp.fd = fd;
+ args_rsp.ret = ret;
+ args_rsp.rsp = VTZF_TLOG_GET_VER + 1;
+ strcpy(args_rsp.teeVersion, g_teeVersion);
+ ret = write(sock, &args_rsp, sizeof(args_rsp));
+ }
+ }
+ }
+
+ return NULL;
+}
+*/
+
+int g_rsp = 250;
+int rsp2 = 315;
+
+void serial_testA(void* argp) {
+ struct_testA* sa = (struct_testA*)argp;
+ struct_vtzb_packet_cmd_test* vtzbp_cmd_test = sa->vtzbp_cmd;
+ struct_vtzb_packet_rsp_test packet_rsp1;
+ sleep(2);
+ packet_rsp1.ret = g_rsp++;
+ packet_rsp1.rsp = vtzbp_cmd_test->seq_num + 1;
+ debug(" packet_rsp1.rsp = %d , packet_rsp1.ret =%d \n", packet_rsp1.rsp,
+ packet_rsp1.ret);
+ int ret = write(sa->fd, &packet_rsp1, sizeof(struct_vtzb_packet_rsp_test));
+ if (ret) {
+ }
+
+}
+
+
+struct serial_port_list g_serial_list;
+struct pollfd g_pollfd[SERIAL_PORT_NUM];
+int g_pollfd_len = 0;
+
+void serial_port_list_destroy()
+{
+ debug("释放串口资源\n");
+ struct serial_port_file *serial_port = NULL;
+ struct serial_port_file *tmp = NULL;
+ (void)pthread_mutex_lock(&g_serial_list.lock);
+ LIST_FOR_EACH_ENTRY_SAFE(serial_port, tmp, &g_serial_list.head, head) {
+ if (serial_port->rd_buf) {
+ free(serial_port->rd_buf);
+ serial_port->rd_buf = NULL;
+ }
+ if (serial_port->opened) {
+ close(serial_port->sock);
+ }
+ ListRemoveEntry(&serial_port->head);
+ free(serial_port);
+ }
+
+ (void)pthread_mutex_unlock(&g_serial_list.lock);
+}
+
+static int serial_port_list_init()
+{
+ int i;
+ struct serial_port_file *serial_port;
+// g_serial_list.lock = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_init(&g_serial_list.lock, NULL);
+ ListInit(&g_serial_list.head);
+ for ( i = 0; i < SERIAL_PORT_NUM; i++)
+ {
+ serial_port = (struct serial_port_file *)malloc(sizeof(struct serial_port_file));
+ memset_s(serial_port, sizeof(struct serial_port_file), 0, sizeof(struct serial_port_file));
+ sprintf(serial_port->path, "%s%d", VTZB_CHAR_DEV, i);
+ debug("path = %s \n", serial_port->path);
+ serial_port->opened = false;
+ serial_port->rd_buf = (char *)malloc(BUF_LEN_MAX_RD);
+ if (!serial_port->rd_buf) {
+ tloge("Failed to allocate memory for rd_buf\n");
+ free(serial_port);
+ goto ERR;
+ }
+ ListInsertTail(&g_serial_list.head, &serial_port->head);
+ }
+
+ return 0;
+ERR:
+ serial_port_list_destroy();
+ return -ENOMEM;
+}
+
+void check_stat_serial_port()
+{
+ int ret;
+ struct serial_port_file *serial_port;
+ (void)pthread_mutex_lock(&g_serial_list.lock);
+ LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){
+ if (serial_port->opened == false) {
+ ret = access(serial_port->path, R_OK | W_OK);
+ if (ret == 0) {
+ ret = connect_domsock_chardev(serial_port->path, &(serial_port->sock));
+ if (ret < 0) {
+ debug("connect_domsock_chardev(%s) failed, ret = %d \n", serial_port->path, ret);
+ } else {
+ debug("open new socket \n");
+ serial_port->opened = true;
+ g_pollfd[g_pollfd_len].fd = serial_port->sock;
+ g_pollfd[g_pollfd_len].events = POLLIN;
+ serial_port->index = g_pollfd_len;
+ g_pollfd_len++;
+ }
+ } else{
+ debug(" can't access \n");
+ }
+ } else {
+ ret = access(serial_port->path, R_OK | W_OK);
+ if (ret) {
+ debug(" disconnetc socket \n");
+ close(serial_port->sock);
+ g_pollfd[serial_port->index] = g_pollfd[g_pollfd_len - 1];
+ g_pollfd_len--;
+ serial_port->opened = false;
+ }
+ }
+ }
+ (void)pthread_mutex_unlock(&g_serial_list.lock);
+}
+
+void *get_rd_buf(int serial_port_fd)
+{
+ struct serial_port_file *serial_port;
+ LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){
+ if (serial_port->sock == serial_port_fd) {
+ return serial_port->rd_buf;
+ }
+ }
+ return NULL;
+}
+
+void *get_serial_port_file(int serial_port_fd)
+{
+ struct serial_port_file *serial_port;
+ LIST_FOR_EACH_ENTRY(serial_port, &g_serial_list.head, head){
+ if (serial_port->sock == serial_port_fd) {
+ return serial_port;
+ }
+ }
+ return NULL;
+}
+
+static void open_tzdriver(struct_packet_cmd_open_tzd *packet_cmd, int serial_port_fd)
+{
+ debug("*****cmd is open_tzdriver*****\n");
+ int fd = -1;
+ int ret;
+ struct_packet_rsp_open_tzd packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+
+ debug("packet_cmd->flag =%d \n",packet_cmd->flag);
+
+ if (packet_cmd->flag == TC_NS_CLIENT_DEV_FLAG) {
+ fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR);
+
+ } else if(packet_cmd->flag == TC_PRIVATE_DEV_FLAG) {
+ fd = open(TC_TEECD_PRIVATE_DEV_NAME, O_RDWR);
+ } else if (packet_cmd->flag == TC_CVM_DEV_FLAG) {
+ fd = open(TC_NS_CVM_DEV_NAME, O_RDWR);
+ }
+ packet_rsp.ptzfd = fd;
+ if (fd < 0) {
+ tloge("open tee client dev failed, fd is %d\n", fd);
+ packet_rsp.ret = fd;
+ goto END;
+ }
+ packet_rsp.ret = 0;
+ debug(" ptzfd = %d \n", packet_rsp.ptzfd);
+ debug(" qemu_pid|vmid = %d \n", packet_cmd->vmid);
+
+ ret = ioctl(fd, TC_NS_CLIENT_IOCTL_SET_VM_FLAG, packet_cmd->vmid);
+
+ if (ret) {
+ debug("set VM flag failed, ret = %d\n", ret);
+ }
+END:
+ if(serial_port_fd == 999){
+ return ;
+ }
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void free_agent_buf(int ptzfd)
+{
+ struct ListNode* ptr = NULL;
+ struct ListNode* n = NULL;
+ struct_agent_args* agent_args = NULL;
+ unsigned long buf[2];
+ pthread_mutex_lock(&g_mutex_agent_buf);
+ debug(" free_agent_buf \n");
+ if (!LIST_EMPTY(&g_agent_buf_list)) {
+ LIST_FOR_EACH_SAFE(ptr, n, &g_agent_buf_list) {
+ struct_agent_args* tmp =
+ CONTAINER_OF(ptr, struct_agent_args, node);
+ if (tmp->dev_fd == ptzfd) {
+ ListRemoveEntry(&(tmp->node));
+ /*unregister*/
+ //free(tmp);
+ agent_args = tmp;
+ }
+ }
+ }
+ pthread_mutex_unlock(&g_mutex_agent_buf);
+ if (agent_args) {
+ debug(" unregister \n");
+ buf[0] = agent_args->args.id;
+ int ret = ioctl(ptzfd, TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT, buf);
+ if (ret) {
+ tloge("ioctl failed\n");
+ debug(" ioctl unregister failed\n");
+ }
+ free(agent_args);
+ } else {
+ debug(" not find!\n");
+ }
+}
+
+static void close_tzdriver(struct_packet_cmd_close_tzd *packet_cmd, int serial_port_fd)
+{
+ debug("*****cmd is close TZdriver***** \n");
+ struct_packet_rsp_close_tzd packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ packet_rsp.ret = 0;
+
+ if (write(serial_port_fd, &packet_rsp, sizeof(packet_rsp)) != sizeof(packet_rsp)) {
+ tloge("close ptzfd send to VM failed \n");
+ }
+/* 应建立一个链表,qemu_pid 与 ptzfd相对应,防止冒充关闭ptzfd*/
+ if (packet_cmd->ptzfd > 2){
+ /*释放内存资源*/
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ free_agent_buf(packet_cmd->ptzfd);
+ debug(" after free_agent_buf\n");
+ close(packet_cmd->ptzfd);
+ }
+
+
+}
+
+static void log_in_NonHidl(struct_packet_cmd_login_non *packet_cmd, int serial_port_fd)
+{
+ debug("*****cmd is log_in_nonhidl \n");
+ int ret;
+ struct_packet_rsp_login packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOGIN, NULL);
+ packet_rsp.ret = ret;
+
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void log_in(struct_packet_cmd_login *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_login packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOGIN, packet_cmd->cert_buffer);
+ packet_rsp.ret = ret;
+ debug("***** cmd is login ***** \n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void get_tee_ver(struct_packet_cmd_getteever *packet_cmd, int serial_port_fd)
+{
+
+ int ret;
+ struct_packet_rsp_getteever packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_GET_TEE_VERSION, &packet_rsp.tee_ver);
+ debug("***** cmd is get ver ***** \n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ packet_rsp.ret = ret;
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void get_tee_info(struct_packet_cmd_getteeinfo *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_getteeinfo packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_GET_TEE_INFO, &packet_rsp.info);
+ debug("***** cmd is get tee info ***** \n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ packet_rsp.ret = ret;
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void SyncSysTime(struct_packet_cmd_synctime *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_synctime packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SYC_SYS_TIME, &packet_cmd->tcNsTime);
+ packet_rsp.ret = ret;
+ debug("***** cmd is SyncSysTime *****\n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void open_session(struct_packet_cmd_session *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_session packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ debug("***** cmd is open session *****\n");
+ debug(" cliContext.login.method = %d\n",packet_cmd->cliContext.login.method);
+ debug(" cliContext.file_size = %d \n ", packet_cmd->cliContext.file_size);
+ debug(" cliContext.file_buffer = %p \n ", packet_cmd->cliContext.file_buffer);
+
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SES_OPEN_REQ, &packet_cmd->cliContext);
+ packet_rsp.ret = ret;
+ packet_rsp.cliContext = packet_cmd->cliContext;
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ debug(" session_id = %d \n",packet_rsp.cliContext.session_id);
+
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void close_session(struct_packet_cmd_session *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_general packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ, &packet_cmd->cliContext);
+ packet_rsp.ret = ret;
+ debug("***** cmd is close session *****\n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static int process_address(struct_packet_cmd_send_cmd *packet_cmd)
+{
+ int index;
+ int icount = 0;
+ int ret = 0;
+ uint32_t paramTypes[TEEC_PARAM_NUM];
+ uint64_t *vm_hvas = (uint64_t *)packet_cmd->cliContext.file_buffer;
+
+ for (index = 0; index < TEEC_PARAM_NUM; index++) {
+ paramTypes[index] =
+ TEEC_PARAM_TYPE_GET(packet_cmd->cliContext.paramTypes, index);
+ if (IS_PARTIAL_MEM(paramTypes[index])) {
+ void* vm_buffer = (void*)packet_cmd->addrs[index];
+
+ bool b_found = false;
+ struct ListNode* ptr = NULL;
+ pthread_mutex_lock(&g_mutex_shrd_mem);
+ if (!LIST_EMPTY(&g_shrd_mem_list)) {
+ LIST_FOR_EACH(ptr, &g_shrd_mem_list) {
+ struct_shrd_mem* shrd_mem =
+ CONTAINER_OF(ptr, struct_shrd_mem, node);
+ if (shrd_mem->vm_buffer == vm_buffer) {
+ vm_hvas[index] = packet_cmd->cliContext.params[index].memref.buffer
+ | (uint64_t)packet_cmd->cliContext.params[index].memref.buffer_h_addr << H_OFFSET;
+ /* 切换为host上的用户地址 */
+ packet_cmd->cliContext.params[index].memref.buffer =
+ (unsigned int)(uintptr_t)shrd_mem->buffer;
+ packet_cmd->cliContext.params[index].memref.buffer_h_addr =
+ ((unsigned long long)(uintptr_t)shrd_mem->buffer) >> H_OFFSET;
+ icount++;
+ b_found = true;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&g_mutex_shrd_mem);
+ if (b_found == false) {
+ tloge("can't find mmap buffer \n");
+ debug("can't find mmap buffer \n");
+ ret = -1;
+ return ret;
+ }
+ }
+ }
+ if (icount ==0) {
+ packet_cmd->cliContext.file_buffer = NULL;
+ }
+ return ret;
+}
+
+static void send_cmd(struct_packet_cmd_send_cmd *packet_cmd, int serial_port_fd)
+{
+ //debug("***** cmd is invoke cmd *****\n");
+ int ret = -1;
+ struct timeval start, end;
+ uint32_t cost = 0;
+ struct_packet_rsp_send_cmd packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ void *vm_hvas = (void *)malloc(sizeof(void *)*TEEC_PARAM_NUM);
+ packet_cmd->cliContext.file_buffer = vm_hvas;
+ packet_cmd->cliContext.file_size = sizeof(void *)*TEEC_PARAM_NUM;
+ /* mmap */
+ gettimeofday(&start, NULL);
+ if (!process_address(packet_cmd)) {
+ debug(" process addrs success \n");
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_CMD_REQ, &packet_cmd->cliContext);
+ }
+ gettimeofday(&end, NULL);
+ cost = (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec);
+ (void)cost;
+ //printf("invoke cmd cost : %f us\n", cost * 1.0);
+ free(vm_hvas);
+ packet_rsp.ret = ret;
+ packet_rsp.cliContext = packet_cmd->cliContext;
+ //debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ //debug(" ret = %d \n", ret);
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void register_agent(struct_packet_cmd_regagent *packet_cmd, int serial_port_fd)
+{
+ debug("***** cmd is register_agent *****\n");
+ int ret;
+ struct_packet_rsp_regagent packet_rsp;
+ unsigned long buf[2];
+ buf[0] = (unsigned long)(&packet_cmd->args);
+ debug(" buf_size = %u\n", packet_cmd->args.bufferSize);
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_REGISTER_AGENT, buf);
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ if (!ret) {
+ /* 将agent buffer加入链表 */
+ struct_agent_args* tmp = (struct_agent_args*)malloc(sizeof(struct_agent_args));
+ ListInit(&tmp->node);
+ tmp->dev_fd = packet_cmd->ptzfd;
+ tmp->args = packet_cmd->args;
+ tmp->vmaddr = packet_cmd->vmaddr;
+ pthread_mutex_lock(&g_mutex_agent_buf);
+ ListInsertTail(&g_agent_buf_list, &tmp->node);
+ pthread_mutex_unlock(&g_mutex_agent_buf);
+ }
+
+ packet_rsp.ret = ret;
+ packet_rsp.args = packet_cmd->args;
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void load_sec_file(struct_packet_cmd_load_sec *packet_cmd, int serial_port_fd)
+{
+ int ret;
+ struct_packet_rsp_load_sec packet_rsp;
+ //unsigned long buf[2];
+ //buf[0] = (unsigned long)(&packet_cmd->ioctlArg);
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ debug("***** cmd is load_sec_file *****\n");
+ debug(" secFileInfo.fileSize = %d \n", packet_cmd->ioctlArg.secFileInfo.fileSize);
+ debug(" ioctlArg.fileBuffer = %p \n", packet_cmd->ioctlArg.fileBuffer);
+ debug(" ioctlArg.secFileInfo.fileType = %d \n",packet_cmd->ioctlArg.secFileInfo.fileType);
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_LOAD_APP_REQ, &packet_cmd->ioctlArg);
+ packet_rsp.ret = ret;
+ packet_rsp.ioctlArg = packet_cmd->ioctlArg;
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void wait_event(struct_packet_cmd_event *packet_cmd, int serial_port_fd)
+{
+ debug("***** cmd is wait event *****\n");
+ int ret = -EFAULT;
+ struct_packet_rsp_general packet_rsp;
+ unsigned long buf[2];
+ struct ListNode* ptr = NULL;
+ bool bfind = false;
+
+ buf[0] = packet_cmd->agent_id;
+
+ pthread_mutex_lock(&g_mutex_agent_buf);
+ if (!LIST_EMPTY(&g_agent_buf_list)) {
+ LIST_FOR_EACH(ptr, &g_agent_buf_list) {
+ struct_agent_args* agent_args =
+ CONTAINER_OF(ptr, struct_agent_args, node);
+ if (agent_args->args.id == packet_cmd->agent_id) {
+ buf[1] = (unsigned long)agent_args->vmaddr;
+ bfind = true;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&g_mutex_agent_buf);
+ if (bfind) {
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_WAIT_EVENT, buf);
+ }
+ debug(" after wait, ret = %d\n", ret);
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ packet_rsp.ret = ret;
+
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void sent_event_response(struct_packet_cmd_event *packet_cmd, int serial_port_fd)
+{
+ debug("***** cmd is sent_event_response *****\n");
+ int ret = -EFAULT;
+ struct_packet_rsp_general packet_rsp;
+ unsigned long buf[2];
+ bool bfind = false;
+ struct ListNode* ptr = NULL;
+ buf[0] = packet_cmd->agent_id;
+ pthread_mutex_lock(&g_mutex_agent_buf);
+ if (!LIST_EMPTY(&g_agent_buf_list)) {
+ LIST_FOR_EACH(ptr, &g_agent_buf_list) {
+ struct_agent_args* agent_args =
+ CONTAINER_OF(ptr, struct_agent_args, node);
+ if (agent_args->args.id == packet_cmd->agent_id) {
+ buf[1] = (unsigned long)agent_args->vmaddr;
+ bfind = true;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&g_mutex_agent_buf);
+
+ if (bfind) {
+ ret = ioctl(packet_cmd->ptzfd, TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, buf);
+ }
+
+ debug(" after respomse, ret = %d\n", ret);
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ debug(" ret = %d \n", ret);
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+ packet_rsp.ret = ret;
+
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+}
+
+static void vtz_dommap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd)
+{
+ int ret = 0;
+ struct_packet_rsp_mmap packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+
+ void *buffer = mmap(0, (unsigned long)packet_cmd->size, (PROT_READ | PROT_WRITE), MAP_SHARED,
+ packet_cmd->ptzfd, (long)(packet_cmd->offset * (uint32_t)PAGE_SIZE));
+ printf("mmap buffer = %p \n", buffer);
+ if (buffer == MAP_FAILED) {
+ tloge("mmap failed\n");
+ debug("mmap failed \n");
+ ret = -ENOMEM;
+ }
+
+ debug(" mmap ret = %d \n", ret);
+ packet_rsp.ret = ret;
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+ debug(" vm_buffer = %p\n", packet_cmd->buffer);
+ struct_shrd_mem* tmp = (struct_shrd_mem*)malloc(sizeof(struct_shrd_mem));
+ ListInit(&tmp->node);
+ tmp->buffer = buffer;
+ tmp->vm_buffer = (void*)packet_cmd->buffer;
+ tmp->buffer_size = (size_t)packet_cmd->size;
+ tmp->dev_fd = packet_cmd->ptzfd;
+
+ pthread_mutex_lock(&g_mutex_shrd_mem);
+ ListInsertTail(&g_shrd_mem_list, &tmp->node);
+ pthread_mutex_unlock(&g_mutex_shrd_mem);
+}
+
+static void vtz_dounmmap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd)
+{
+ int ret = 0;
+ struct_packet_rsp_mmap packet_rsp;
+ packet_rsp.seq_num = packet_cmd->seq_num + 1;
+
+ void* buffer = NULL;
+ uint32_t buffer_size;
+ struct ListNode* ptr = NULL;
+ struct ListNode* n = NULL;
+
+ packet_rsp.ret = ret;
+ ret = write(serial_port_fd, &packet_rsp, sizeof(packet_rsp));
+ if (ret != sizeof(packet_rsp)) {
+ tloge("send to VM failed \n");
+ }
+ pthread_mutex_lock(&g_mutex_shrd_mem);
+ if (!LIST_EMPTY(&g_shrd_mem_list)) {
+ LIST_FOR_EACH_SAFE(ptr, n, &g_shrd_mem_list) {
+ struct_shrd_mem* shrd_mem =
+ CONTAINER_OF(ptr, struct_shrd_mem, node);
+ if (shrd_mem->vm_buffer == (void*)packet_cmd->buffer) {
+ ListRemoveEntry(&(shrd_mem->node));
+ buffer = shrd_mem->buffer;
+ buffer_size = shrd_mem->buffer_size;
+ free(shrd_mem);
+ }
+ }
+ }
+ pthread_mutex_unlock(&g_mutex_shrd_mem);
+ if (buffer != NULL) {
+ debug(" munmap buffer = %p \n", buffer);
+ ret = munmap(buffer, (size_t)buffer_size);
+ if (ret) {
+ tloge("Release SharedMemory failed, munmap error\n");
+ debug("Release SharedMemory failed, munmap error\n");
+ }
+ }
+}
+
+static void vtz_mmap(struct_packet_cmd_mmap *packet_cmd, int serial_port_fd)
+{
+ debug("*****cmd is mmap*****\n");
+ debug(" ptzfd = %d \n", packet_cmd->ptzfd);
+ if (packet_cmd->cmd == VTZB_MMAP) {
+ vtz_dommap(packet_cmd, serial_port_fd);
+ } else {
+ vtz_dounmmap(packet_cmd, serial_port_fd);
+ }
+
+}
+
+
+void *thread_entry(void *args)
+{
+ uint32_t ui32_cmd;
+ int serial_port_fd = (int)((uint64_t)args);
+ struct serial_port_file *serial_port = get_serial_port_file(serial_port_fd);
+
+ char* rd_buf = serial_port->rd_buf;
+ int buf_size = serial_port->buf_size;
+
+ if (buf_size >= 4) {
+ ui32_cmd = *(uint32_t*)rd_buf;
+ } else {
+ return NULL;
+ }
+
+ ui32_cmd = *(uint32_t*)rd_buf;
+ debug("received message packet from guest: \n");
+ debug("cmd = %d, 0x%8.8x \n", ui32_cmd, ui32_cmd);
+
+ switch (ui32_cmd)
+ {
+ case VTZB_OPEN_TZD:
+ debug("before \n");
+ if (buf_size >= (int)sizeof(struct_packet_cmd_open_tzd)) {
+ debug("before open tz \n");
+ (void)open_tzdriver((struct_packet_cmd_open_tzd *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_CLOSE_TZD:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_close_tzd)) {
+ (void)close_tzdriver((struct_packet_cmd_close_tzd *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_LOG_IN_NHIDL:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_login_non)) {
+ (void)log_in_NonHidl((struct_packet_cmd_login_non *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_GET_TEE_VERSION:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_getteever)) {
+ (void)get_tee_ver((struct_packet_cmd_getteever *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_GET_TEE_INFO:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_getteeinfo)) {
+ (void)get_tee_info((struct_packet_cmd_getteeinfo *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_LATE_INIT:
+ break;
+ case VTZB_SYNC_TIME:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_synctime)) {
+ (void)SyncSysTime((struct_packet_cmd_synctime *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_LOG_IN:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_login)) {
+ (void)log_in((struct_packet_cmd_login *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZF_LOAD_SEC:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_load_sec)) {
+ (void)load_sec_file((struct_packet_cmd_load_sec *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_OPEN_SESSION:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_session)) {
+ (void)open_session((struct_packet_cmd_session *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_CLOSE_SESSION:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_session)) {
+ (void)close_session((struct_packet_cmd_session *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_SEND_CMD:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_send_cmd)) {
+ (void)send_cmd((struct_packet_cmd_send_cmd *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_FS_REGISTER_AGENT:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_regagent)) {
+ (void)register_agent((struct_packet_cmd_regagent *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZF_WAIT_EVENT:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_event)) {
+ (void)wait_event((struct_packet_cmd_event *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZF_SEND_EVENT_RESPONSE:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_event)) {
+ (void)sent_event_response((struct_packet_cmd_event *)rd_buf, serial_port_fd);
+ }
+ break;
+ case VTZB_MMAP:
+ case VTZB_MUNMAP:
+ if (buf_size >= (int)sizeof(struct_packet_cmd_mmap)) {
+ (void)vtz_mmap((struct_packet_cmd_mmap *)rd_buf, serial_port_fd);
+ }
+ break;
+
+ case 520:
+ debug(" \n");
+ struct_testA ssa;
+ ssa.fd = serial_port_fd;
+ ssa.vtzbp_cmd = (struct_vtzb_packet_cmd_test*)rd_buf;
+ serial_testA(&ssa);
+ break;
+ case 618:
+ debug(" \n");
+ struct_vtzb_packet_cmd_test *vtzbp_cmd_test = (struct_vtzb_packet_cmd_test*)rd_buf;
+ struct_vtzb_packet_rsp_test packet_rsp2;
+ packet_rsp2.ret = rsp2++;
+ packet_rsp2.rsp = vtzbp_cmd_test->seq_num + 1;
+ // sleep(2);
+ debug(" packet_rsp2.rsp = %d , packet_rsp2.ret =%d \n",
+ packet_rsp2.rsp, packet_rsp2.ret);
+ buf_size = write(serial_port_fd, &packet_rsp2,
+ sizeof(struct_vtzb_packet_rsp_test));
+ break;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+void process_event(int fd)
+{
+ int ret;
+ //char* rd_buf = (char *)get_rd_buf(fd);
+ struct serial_port_file *serial_port = get_serial_port_file(fd);
+ if (!serial_port || !serial_port->rd_buf){
+ tloge(" rd_buf is NULL \n");
+ return ;
+ }
+ ret = read(fd, serial_port->rd_buf, BUF_LEN_MAX_RD);
+ if (ret < 0) {
+ tloge("read domain socket failed \n");
+ debug("read domain socket failed \n");
+ return ;
+ }
+ if (ret == 0) {
+ return ;
+ }
+ serial_port->buf_size = ret;
+ thread_pool_submit(&pool, thread_entry, (void *)((uint64_t)fd));
+}
+
+// int main(int argc, const char *argv[])
+int main() {
+ int ret = 0;
+ int i;
+
+ thread_pool_init(&pool);
+
+ serial_port_list_init();
+
+ while (1) {
+ check_stat_serial_port();
+
+ ret = safepoll(g_pollfd, g_pollfd_len, -1);
+ if (ret == -1) {
+ tloge("pollfd failed, ret = %d \n", ret);
+ return -1;
+ }
+ if (ret == 0) {
+ tloge("pollfd timeout \n");
+ continue;
+ }
+
+ for (i = 0; i < g_pollfd_len; i++) {
+ if (g_pollfd[i].revents & POLLIN) {
+ //pthread_t ntid;
+ //pthread_create(&ntid, NULL, thread_entry, &g_pollfd[i].fd);
+ //(void)thread_entry(g_pollfd[i].fd);
+ process_event(g_pollfd[i].fd);
+ }
+ }
+ }
+
+ serial_port_list_destroy();
+ return nr_failed;
+}
+
+
diff --git a/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..981cf944005ddc133e5a83ae6d86ad876d8e2c65
--- /dev/null
+++ b/trustzone-awared-vm/host/vtzb_proxy/vtzb_proxy.h
@@ -0,0 +1,487 @@
+#ifndef __VTZB_PROXY_H__
+#define __VTZB_PROXY_H__
+
+/*
+ */
+
+#include
+#include
+#include "tc_ns_client.h"
+#include "tee_sys_log.h"
+// #include "tee_auth_common.h"
+#include "tee_client_list.h"
+
+//#define DEBUG 1
+
+#define VTZB_CHAR_DEV "/tmp/vm_vtzb_sock"
+//#define VM_NUM_MAX 2
+#define SERIAL_PORT_NUM 5
+#define UNIX_PATH_MAX 108
+#define H_OFFSET 32
+
+#define BUF_MAX_SIZE 2048
+#define BUF_LENGTH 4080
+#define BUF_LEN_MAX_RD 1024 * 8
+
+#define TC_NS_CLIENT_DEV_FLAG 3
+#define TC_PRIVATE_DEV_FLAG 4
+#define TC_CVM_DEV_FLAG 5
+
+
+#define VTZB_OPEN_TZD 15
+#define VTZB_CLOSE_TZD 17
+#define VTZB_LOG_IN_NHIDL 19
+#define VTZB_GET_TEE_VERSION 21
+#define VTZB_GET_TEE_INFO 23
+#define VTZB_LATE_INIT 25
+#define VTZB_SYNC_TIME 27
+#define VTZB_LOG_IN 29
+#define VTZB_OPEN_SESSION 31
+#define VTZB_SEND_CMD 33
+#define VTZB_CANCEL_CMD 35
+#define VTZB_MMAP 37
+#define VTZB_MUNMAP 39
+#define VTZB_CLOSE_SESSION 41
+#define VTZB_CLOSE_PTZDEV 43
+#define VTZB_FS_REGISTER_AGENT 45
+#define VTZF_WAIT_EVENT 49
+#define VTZF_SEND_EVENT_RESPONSE 51
+#define VTZF_LOAD_SEC 53
+#define VTZB_TEST 47
+
+#define VTZB_RSP_UNKOWN 0xfffffffe
+
+// for tlog
+#define TEELOGGERIO 0xBE
+#define GET_VERSION_BASE 5
+#define TEELOGGER_GET_VERSION _IOR(TEELOGGERIO, GET_VERSION_BASE, char[256U])
+
+#define TEEC_PARAM_TYPE_GET(paramTypes, index) \
+ (((paramTypes) >> (4 * (index))) & 0x0F)
+
+#define IS_PARTIAL_MEM(paramType) \
+ (((paramType) == TEEC_MEMREF_WHOLE) || \
+ ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \
+ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || \
+ ((paramType) == TEEC_MEMREF_PARTIAL_INOUT))
+
+#define PAGE_SIZE getpagesize()
+
+typedef struct {
+ char path[UNIX_PATH_MAX];
+ int sock;
+} char_dev;
+
+typedef struct {
+ void* vm_buffer;
+ void* buffer;
+ uint32_t buffer_size;
+ int32_t dev_fd;
+ struct ListNode node;
+} struct_shrd_mem;
+
+typedef struct {
+ struct AgentIoctlArgs args;
+ int32_t dev_fd;
+ void *vmaddr;
+ struct ListNode node;
+} struct_agent_args;
+
+struct char_dev_list {
+ char_dev char_dev_vtzb;
+ bool opened;
+ int index;
+};
+
+typedef struct {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint16_t clock_seq;
+ uint16_t node0;
+ uint16_t node1;
+ uint16_t node2;
+} struct_uuid;
+
+//////////////////////
+
+struct serial_port_list {
+ pthread_mutex_t lock;
+ struct ListNode head;
+};
+
+struct serial_port_file {
+ char path[UNIX_PATH_MAX];
+ int sock;
+ bool opened;
+ int index;
+ struct ListNode head;
+ char *rd_buf;
+ int buf_size;
+};
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_general;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num; // second
+ uint32_t vmid;
+ uint32_t flag;
+} struct_packet_cmd_open_tzd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ int32_t ptzfd;
+} struct_packet_rsp_open_tzd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num; // second
+ int32_t ptzfd;
+} struct_packet_cmd_close_tzd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_close_tzd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+} struct_packet_cmd_getteeinfo;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ TC_NS_TEE_Info info;
+} struct_packet_rsp_getteeinfo;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+} struct_packet_cmd_getteever;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ uint32_t tee_ver; // 4, 12 bytes
+} struct_packet_rsp_getteever;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+ TC_NS_Time tcNsTime;
+} struct_packet_cmd_synctime;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_synctime;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+ uint8_t cert_buffer[BUF_MAX_SIZE];
+} struct_packet_cmd_login;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+} struct_packet_cmd_login_non;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_login;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ int32_t ptzfd;
+ int32_t cpu_index;
+ struct SecLoadIoctlStruct ioctlArg;
+} struct_packet_cmd_load_sec;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ struct SecLoadIoctlStruct ioctlArg;
+} struct_packet_rsp_load_sec;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd; // 4, 8 bytes
+ int32_t cpu_index; // 4, 12 bytes
+ TC_NS_ClientContext cliContext;
+} struct_packet_cmd_session;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ TC_NS_ClientContext cliContext;
+} struct_packet_rsp_session;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ int32_t ptzfd;
+ int32_t cpu_index;
+ unsigned long long addrs[TEEC_PARAM_NUM];
+ TC_NS_ClientContext cliContext;
+} struct_packet_cmd_send_cmd;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ TC_NS_ClientContext cliContext;
+} struct_packet_rsp_send_cmd;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ int32_t ptzfd;
+ uint64_t buffer;
+ uint32_t size;
+ uint32_t offset;
+} struct_packet_cmd_mmap;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_mmap;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ int32_t ptzfd;
+ void *vmaddr;
+ struct AgentIoctlArgs args;
+} struct_packet_cmd_regagent;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ struct AgentIoctlArgs args;
+} struct_packet_rsp_regagent;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ int32_t ptzfd;
+ uint32_t agent_id;
+} struct_packet_cmd_event;
+
+//////////////////
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t cmd; // 4, 4 bytes
+ int32_t seq_num;
+} struct_vtzb_packet_cmd_test;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzb_packet_rsp_test;
+
+typedef struct {
+ struct_vtzb_packet_cmd_test* vtzbp_cmd;
+ int fd;
+} struct_testA;
+
+/*
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzb_packet_rsp_general;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+} struct_vtzb_packet_cmd_getteever;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ uint32_t tee_ver; // 4, 12 bytes
+} struct_vtzb_packet_rsp_getteever;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t cmd; // 4, 4 bytes
+ TC_NS_Time tcNsTime; // 8, 12 bytes
+} struct_vtzb_packet_cmd_synctime;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzb_packet_rsp_synctime;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t cert_buffer_size; // 4, 8 bytes
+ uint8_t cert_buffer[BUF_MAX_SIZE];
+} struct_vtzb_packet_cmd_login;
+
+typedef struct {
+ // struct_uuid vm_uuid;
+ // uint64_t qemu_process_id;
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ int32_t fd;
+} struct_vtzb_packet_rsp_login;
+
+
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ int32_t ptzfd; // 4, 8 bytes
+ int cpu_index; // 4, 12 bytes
+ TC_NS_ClientContext cliContext;
+ pid_t pid;
+} struct_vtzb_packet_cmd_session;
+
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ TC_NS_ClientContext cliContext;
+} struct_vtzb_packet_rsp_session;
+
+typedef struct {
+ pid_t pid;
+ unsigned long long buffers[TEEC_PARAM_NUM];
+ TC_NS_ClientContext cliContext;
+} struct_clicontext_pid;
+
+typedef struct {
+ pid_t pid;
+ unsigned long long buffers[TEEC_PARAM_NUM];
+ TC_NS_ClientContext cliContext;
+} struct_clicontext_pid_send_cmd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ int32_t ptzfd; // 4, 8 bytes
+ int cpu_index; // 4, 12 bytes
+ unsigned long long addrs[TEEC_PARAM_NUM];
+ TC_NS_ClientContext cliContext;
+ pid_t pid;
+} struct_vtzb_packet_cmd_send_cmd;
+
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ TC_NS_ClientContext cliContext;
+} struct_vtzb_packet_rsp_send_cmd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ int32_t ptzfd; // 4, 8 bytes
+ uint64_t buffer;
+ uint32_t size;
+ uint32_t offset;
+ pid_t pid;
+} struct_vtzb_packet_cmd_mmap;
+
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzb_packet_rsp_mmap;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ int32_t ptzfd; // 4, 8 bytes
+} struct_vtzb_packet_cmd_closeptz;
+
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzb_packet_rsp_closeptz;
+
+typedef struct {
+ struct_vtzb_packet_cmd_login* vtzbp_cmd_login;
+ int fd;
+} struct_log_in;
+
+typedef struct {
+ struct_vtzb_packet_cmd_session* vtzbp_cmd_session;
+ int fd;
+} struct_session;
+
+typedef struct {
+ struct_vtzb_packet_cmd_send_cmd* vtzbp_cmd_send_cmd;
+ int fd;
+} struct_send_cmd;
+
+typedef struct {
+ struct_vtzb_packet_cmd_mmap* vtzbp_cmd_mmap;
+ int fd;
+} struct_mmap;
+
+typedef struct {
+ struct_vtzb_packet_cmd_closeptz* vtzbp_cmd_closeptz;
+ int fd;
+} struct_closeptz;
+
+// for tlog
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t tmp;
+} struct_vtzf_packet_cmd_tlog;
+
+typedef struct {
+ uint32_t rsp; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ int32_t fd; // 4, 12 bytes
+ char teeVersion[256U];
+} struct_vtzf_packet_rsp_tlog;
+*/
+
+#ifdef DEBUG
+void debug(const char* fmt, ...);
+void dump_buff(const char* buffer, size_t bufLen);
+#else
+#define debug(fmt, ...) \
+ do { \
+ } while (0)
+
+#define dump_buff(buffer, bufLen) \
+ do { \
+ } while (0)
+#endif
+
+double __get_us(struct timeval t);
+int connect_domsock_chardev(char* dev_path, int* sock);
+
+/*
+void* vtzb_get_tee_version(void* args);
+void* vtzb_sync_time(void* args);
+void* vtzb_log_in(void* args);
+void* vtzb_opensession(void* args);
+void* vtzb_closesession(void* args);
+void* vtzb_mmap(void* args);
+void* vtzb_munmap(void* args);
+void* vtzb_closeptz(void* args);
+*/
+
+#endif /* __VTZB_PROXY_H__ */
+
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/Makefile b/trustzone-awared-vm/vm/vtzdriver/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e640990b474cafb4c293fb15512a6d0233230e09
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/Makefile
@@ -0,0 +1,32 @@
+#Makefile
+obj-m := vtzfdriver.o
+
+vtzfdriver-objs := vtzf.o
+
+RESULT := $(shell cat /proc/kallsyms | grep vsnprintf_s)
+
+STATUS := $(findstring vsnprintf_s, $(RESULT))
+
+# ifneq ($(STATUS), vsnprintf_s)
+vtzfdriver-objs += libboundscheck/src/memcpy_s.o libboundscheck/src/memset_s.o libboundscheck/src/strcpy_s.o libboundscheck/src/strncpy_s.o \
+libboundscheck/src/memmove_s.o libboundscheck/src/strcat_s.o libboundscheck/src/strncat_s.o libboundscheck/src/strtok_s.o \
+libboundscheck/src/securecutil.o libboundscheck/src/secureprintoutput_a.o libboundscheck/src/snprintf_s.o libboundscheck/src/vsnprintf_s.o
+# endif
+
+KERN_VER = $(shell uname -r)
+KERN_DIR = /lib/modules/$(KERN_VER)/build
+
+EXTRA_CFLAGS += -fstack-protector-strong -DCONFIG_AUTH_ENHANCE
+EXTRA_CFLAGS += -I$(PWD)/libboundscheck/include/
+EXTRA_CFLAGS += -I$(PWD)/inc/
+
+all:
+ make -C $(KERN_DIR) M=`pwd` modules
+
+
+.PHONY: clean
+clean:
+ # make -C $(KERN_DIR) M=`pwd` modules clean
+ -rm -vrf *.o *.ko
+ -rm -vrf *.order *.symvers *.mod.c *.mod.o .tmp_versions .*o.cmd .*.o.d
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_client.h b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_client.h
new file mode 100644
index 0000000000000000000000000000000000000000..d88f4d315726d5def3ba7023b8d6c44bbe1d416f
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_client.h
@@ -0,0 +1,213 @@
+/*
+ * tc_ns_client.h
+ *
+ * data structure declaration for nonsecure world
+ *
+ * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef TC_NS_CLIENT_H
+#define TC_NS_CLIENT_H
+
+#include
+#include
+
+#define UUID_LEN 16
+#define PARAM_NUM 4
+#define ADDR_TRANS_NUM 32
+
+#define teec_param_types(param0_type, param1_type, param2_type, param3_type) \
+ ((param3_type) << 12 | (param2_type) << 8 | \
+ (param1_type) << 4 | (param0_type))
+
+#define teec_param_type_get(param_types, index) \
+ (((param_types) >> ((index) << 2)) & 0x0F)
+
+#ifndef ZERO_SIZE_PTR
+#define ZERO_SIZE_PTR ((void *)16)
+#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR)
+#endif
+
+#if (KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE)
+#define mm_sem_lock(mm) (mm)->mmap_lock
+#else
+#define mm_sem_lock(mm) (mm)->mmap_sem
+#endif
+
+struct tc_ns_client_login {
+ __u32 method;
+ __u32 mdata;
+};
+
+union tc_ns_client_param {
+ struct {
+ __u32 buffer;
+ __u32 buffer_h_addr;
+ __u32 offset;
+ __u32 h_offset;
+ __u32 size_addr;
+ __u32 size_h_addr;
+ } memref;
+ struct {
+ __u32 a_addr;
+ __u32 a_h_addr;
+ __u32 b_addr;
+ __u32 b_h_addr;
+ } value;
+};
+
+struct tc_ns_client_return {
+ int code;
+ __u32 origin;
+};
+
+struct tc_ns_client_context {
+ unsigned char uuid[UUID_LEN];
+ __u32 session_id;
+ __u32 cmd_id;
+ struct tc_ns_client_return returns;
+ struct tc_ns_client_login login;
+ union tc_ns_client_param params[PARAM_NUM];
+ __u32 param_types;
+ __u8 started;
+ __u32 calling_pid;
+ unsigned int file_size;
+ union {
+ char *file_buffer;
+ struct {
+ uint32_t file_addr;
+ uint32_t file_h_addr;
+ } memref;
+ };
+};
+
+struct tc_ns_client_time {
+ uint32_t seconds;
+ uint32_t millis;
+};
+
+struct tc_ns_tee_info {
+ uint16_t tzdriver_version_major;
+ uint16_t tzdriver_version_minor;
+ uint32_t reserved[15];
+};
+
+enum secfile_type_t {
+ LOAD_TA = 0,
+ LOAD_SERVICE,
+ LOAD_LIB,
+ LOAD_DYNAMIC_DRV,
+ LOAD_PATCH,
+ LOAD_TYPE_MAX,
+};
+
+struct sec_file_info {
+ enum secfile_type_t secfile_type;
+ uint32_t file_size;
+ int32_t sec_load_err;
+};
+
+struct load_secfile_ioctl_struct {
+ struct sec_file_info sec_file_info;
+ unsigned char uuid[UUID_LEN];
+ union {
+ char *file_buffer;
+ struct {
+ uint32_t file_addr;
+ uint32_t file_h_addr;
+ } memref;
+ };
+}__attribute__((packed));
+
+struct agent_ioctl_args {
+ uint32_t id;
+ uint32_t buffer_size;
+ union {
+ void *buffer;
+ unsigned long long addr;
+ };
+};
+
+struct tc_ns_client_crl {
+ union {
+ uint8_t *buffer;
+ struct {
+ uint32_t buffer_addr;
+ uint32_t buffer_h_addr;
+ } memref;
+ };
+ uint32_t size;
+};
+
+#ifdef CONFIG_LOG_POOL_ENABLE
+struct tc_ns_log_pool {
+ uint64_t addr;
+ uint64_t size;
+};
+#endif
+
+#define MAX_SHA_256_SZ 32
+
+#define TC_NS_CLIENT_IOCTL_SES_OPEN_REQ \
+ _IOW(TC_NS_CLIENT_IOC_MAGIC, 1, struct tc_ns_client_context)
+#define TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 2, struct tc_ns_client_context)
+#define TC_NS_CLIENT_IOCTL_SEND_CMD_REQ \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 3, struct tc_ns_client_context)
+#define TC_NS_CLIENT_IOCTL_SHRD_MEM_RELEASE \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 4, unsigned int)
+#define TC_NS_CLIENT_IOCTL_WAIT_EVENT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 5, unsigned int)
+#define TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 6, unsigned int)
+#define TC_NS_CLIENT_IOCTL_REGISTER_AGENT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 7, struct agent_ioctl_args)
+#define TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 8, unsigned int)
+#define TC_NS_CLIENT_IOCTL_LOAD_APP_REQ \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 9, struct load_secfile_ioctl_struct)
+#define TC_NS_CLIENT_IOCTL_NEED_LOAD_APP \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 10, struct tc_ns_client_context)
+#define TC_NS_CLIENT_IOCTL_ALLOC_EXCEPTING_MEM \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 12, unsigned int)
+#define TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 13, struct tc_ns_client_context)
+#define TC_NS_CLIENT_IOCTL_LOGIN \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 14, int)
+#define TC_NS_CLIENT_IOCTL_TUI_EVENT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 16, int)
+#define TC_NS_CLIENT_IOCTL_SYC_SYS_TIME \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 17, struct tc_ns_client_time)
+#define TC_NS_CLIENT_IOCTL_SET_NATIVECA_IDENTITY \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 18, int)
+#define TC_NS_CLIENT_IOCTL_LOAD_TTF_FILE_AND_NOTCH_HEIGHT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 19, unsigned int)
+#define TC_NS_CLIENT_IOCTL_LATEINIT \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 20, unsigned int)
+#define TC_NS_CLIENT_IOCTL_GET_TEE_VERSION \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 21, unsigned int)
+#define TC_NS_CLIENT_IOCTL_UPDATE_TA_CRL\
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 22, struct tc_ns_client_crl)
+#ifdef CONFIG_LOG_POOL_ENABLE
+#define TC_NS_CLIENT_IOCTL_GET_LOG_POOL \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 23, struct tc_ns_log_pool)
+#endif
+#ifdef CONFIG_TEE_TELEPORT_SUPPORT
+#define TC_NS_CLIENT_IOCTL_PORTAL_REGISTER \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 24, struct agent_ioctl_args)
+#define TC_NS_CLIENT_IOCTL_PORTAL_WORK \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 25, struct agent_ioctl_args)
+#endif
+#define TC_NS_CLIENT_IOCTL_GET_TEE_INFO \
+ _IOWR(TC_NS_CLIENT_IOC_MAGIC, 26, struct tc_ns_tee_info)
+#endif
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_log.h b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..33a1e90ae5224885962f03d1f57d35f40cf2910a
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/inc/tc_ns_log.h
@@ -0,0 +1,69 @@
+/*
+ * tc_ns_log.h
+ *
+ * log func declaration
+ *
+ * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef TC_NS_LOG_H
+#define TC_NS_LOG_H
+
+#include
+#if (KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE)
+#include
+#endif
+#include
+enum {
+ TZ_DEBUG_VERBOSE = 0,
+ TZ_DEBUG_DEBUG,
+ TZ_DEBUG_INFO,
+ TZ_DEBUG_WARN,
+ TZ_DEBUG_ERROR,
+};
+#define MOD_TEE "tzdriver"
+
+#define TEE_LOG_MASK TZ_DEBUG_WARN
+
+#define tlogv(fmt, args...) \
+do { \
+ if (TZ_DEBUG_VERBOSE >= TEE_LOG_MASK) \
+ pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \
+} while (0)
+
+
+#define tlogd(fmt, args...) \
+do { \
+ if (TZ_DEBUG_DEBUG >= TEE_LOG_MASK) \
+ pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \
+} while (0)
+
+
+#define tlogi(fmt, args...) \
+do { \
+ if (TZ_DEBUG_INFO >= TEE_LOG_MASK) \
+ pr_info("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \
+} while (0)
+
+
+#define tlogw(fmt, args...) \
+do { \
+ if (TZ_DEBUG_WARN >= TEE_LOG_MASK) \
+ pr_warn("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args); \
+} while (0)
+
+
+#define tloge(fmt, args...) \
+ pr_err("[%s] (%i, %s)%s: " fmt, MOD_TEE, current->pid, current->comm, __func__, ## args)
+
+#endif
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/inc/teek_client_constants.h b/trustzone-awared-vm/vm/vtzdriver/inc/teek_client_constants.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b0b32ac0854a06bc1825538d5f4710ccd4e8ce7
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/inc/teek_client_constants.h
@@ -0,0 +1,211 @@
+/*
+ * teek_client_constants.h
+ *
+ * macro declaration for libteec interface for kernel CA.
+ *
+ * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef TEEK_CLIENT_CONSTANTS_H
+#define TEEK_CLIENT_CONSTANTS_H
+
+enum global_service_cmd_id {
+ GLOBAL_CMD_ID_INVALID = 0x0,
+ GLOBAL_CMD_ID_BOOT_ACK = 0x1,
+ GLOBAL_CMD_ID_OPEN_SESSION = 0x2,
+ GLOBAL_CMD_ID_CLOSE_SESSION = 0x3,
+ GLOBAL_CMD_ID_LOAD_SECURE_APP = 0x4,
+ GLOBAL_CMD_ID_NEED_LOAD_APP = 0x5,
+ GLOBAL_CMD_ID_REGISTER_AGENT = 0x6,
+ GLOBAL_CMD_ID_UNREGISTER_AGENT = 0x7,
+ GLOBAL_CMD_ID_REGISTER_NOTIFY_MEMORY = 0x8,
+ GLOBAL_CMD_ID_UNREGISTER_NOTIFY_MEMORY = 0x9,
+ GLOBAL_CMD_ID_INIT_CONTENT_PATH = 0xa,
+ GLOBAL_CMD_ID_TERMINATE_CONTENT_PATH = 0xb,
+ GLOBAL_CMD_ID_ALLOC_EXCEPTION_MEM = 0xc,
+ GLOBAL_CMD_ID_TEE_TIME = 0xd,
+ GLOBAL_CMD_ID_TEE_INFO = 0xe,
+ GLOBAL_CMD_ID_REGISTER_LOG_MEM = 0xf,
+ GLOBAL_CMD_ID_KILL_TASK = 0x10,
+ GLOBAL_CMD_ID_TUI_EXCEPTION = 0x11,
+ GLOBAL_CMD_ID_ADJUST_TIME = 0x12,
+ GLOBAL_CMD_ID_SET_CA_HASH = 0x13,
+ /* set the Android's build version */
+ GLOBAL_CMD_ID_SET_BUILD_VERSION = 0x14,
+ GLOBAL_CMD_ID_REGISTER_TTF_MEM = 0x15,
+ /* get session key for encrypting dialog */
+ GLOBAL_CMD_ID_GET_SESSION_SECURE_PARAMS = 0x16,
+ GLOBAL_CMD_ID_REGISTER_MAILBOX = 0x17,
+ GLOBAL_CMD_ID_REGISTER_UNUSUAL_TTF_MEM = 0x18,
+ GLOBAL_CMD_ID_REGISTER_ION_MEM = 0x19,
+ GLOBAL_CMD_ID_DUMP_MEMINFO = 0x1a,
+ /* this cmd will be used to service no ca handle cmd */
+ GLOBAL_CMD_ID_SET_SERVE_CMD = 0x1b,
+ GLOBAL_CMD_ID_ADD_DYNAMIC_ION = 0x1c,
+ GLOBAL_CMD_ID_DEL_DYNAMIC_ION = 0x1d,
+ GLOBAL_CMD_ID_RELEASE_ION_SRV = 0x1e,
+ /* this cmd for tui to get notch_size */
+ GLOBAL_CMD_ID_TUI_NOTCH = 0x1f,
+ GLOBAL_CMD_ID_LATE_INIT = 0x20,
+ /* this cmd for tui to get information of foldable screen */
+ GLOBAL_CMD_ID_TUI_FOLD = 0x21,
+ GLOBAL_CMD_ID_GET_TEE_VERSION = 0x22,
+ GLOBAL_CMD_ID_REGISTER_RESMEM = 0x24,
+ GLOBAL_CMD_ID_DUMP_SRV_SESS = 0x25,
+ GLOBAL_CMD_ID_TRACE_ENABLE = 0x26,
+#ifdef CONFIG_TEE_TELEPORT_SUPPORT
+ GLOBAL_CMD_ID_PORTAL_WORK = 0x2b,
+#endif
+ GLOBAL_CMD_ID_REGISTER_HOST_NSID = 0x2d,
+ GLOBAL_CMD_ID_UNKNOWN = 0x7FFFFFFE,
+ GLOBAL_CMD_ID_MAX = 0x7FFFFFFF
+};
+
+enum teec_result {
+ TEEC_SUCCESS = 0x0,
+ TEEC_ERROR_INVALID_CMD = 0x1,
+ TEEC_ERROR_SERVICE_NOT_EXIST = 0x2,
+ TEEC_ERROR_SESSION_NOT_EXIST = 0x3,
+ TEEC_ERROR_SESSION_MAXIMUM,
+ TEEC_ERROR_REGISTER_EXIST_SERVICE,
+ TEEC_ERROR_TAGET_DEAD_FATAL,
+ TEEC_ERROR_READ_DATA,
+ TEEC_ERROR_WRITE_DATA,
+ TEEC_ERROR_TRUNCATE_OBJECT,
+ TEEC_ERROR_SEEK_DATA,
+ TEEC_ERROR_RENAME_OBJECT,
+ TEEC_ERROR_TRUSTED_APP_LOAD_ERROR,
+ TEEC_ERROR_GENERIC = 0xFFFF0000,
+ TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001,
+ TEEC_ERROR_CANCEL = 0xFFFF0002,
+ TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003,
+ TEEC_ERROR_EXCESS_DATA = 0xFFFF0004,
+ TEEC_ERROR_BAD_FORMAT = 0xFFFF0005,
+ TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006,
+ TEEC_ERROR_BAD_STATE = 0xFFFF0007,
+ TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008,
+ TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009,
+ TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A,
+ TEEC_ERROR_NO_DATA = 0xFFFF000B,
+ TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C,
+ TEEC_ERROR_BUSY = 0xFFFF000D,
+ TEEC_ERROR_COMMUNICATION = 0xFFFF000E,
+ TEEC_ERROR_SECURITY = 0xFFFF000F,
+ TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010,
+ TEEC_PENDING = 0xFFFF2000,
+ TEEC_PENDING2 = 0xFFFF2001,
+ TEE_ERROR_TAGET_DEAD = 0xFFFF3024,
+ TEE_ERROR_GT_DEAD = 0xFFFF3124,
+ TEEC_ERROR_MAC_INVALID = 0xFFFF3071,
+ TEEC_CLIENT_INTR = 0xFFFF4000,
+ TEEC_ERROR_TUI_IN_USE = 0xFFFF7110,
+ TEEC_ERROR_TUI_SWITCH_CHANNAL,
+ TEEC_ERROR_TUI_CFG_DRIVER,
+ TEEC_ERROR_TUI_INVALID_EVENT,
+ TEEC_ERROR_TUI_POLL_EVENT,
+ TEEC_ERROR_TUI_CANCELED,
+ TEEC_ERROR_TUI_EXIT,
+ TEEC_ERROR_TUI_NOT_AVAILABLE,
+ TEEC_ERROR_SEC_FLASH_NOT_AVAILABLE,
+ TEEC_ERROR_CA_AUTH_FAIL = 0xFFFFCFE5,
+ TEE_ERROR_AUDIT_FAIL = 0xFFFF9112,
+ TEE_ERROR_IS_DEAD = 0xFFFFABAB,
+};
+
+enum TEEC_ReturnCodeOrigin {
+ TEEC_ORIGIN_API = 0x1,
+ TEEC_ORIGIN_COMMS = 0x2,
+ TEEC_ORIGIN_TEE = 0x3,
+ TEEC_ORIGIN_TRUSTED_APP = 0x4,
+};
+
+enum TEEC_SharedMemCtl {
+ TEEC_MEM_INPUT = 0x1,
+ TEEC_MEM_OUTPUT = 0x2,
+ TEEC_MEM_INOUT = 0x3,
+};
+
+enum TEEC_ParamType {
+ TEEC_NONE = 0x0,
+ TEEC_VALUE_INPUT = 0x01,
+ TEEC_VALUE_OUTPUT = 0x02,
+ TEEC_VALUE_INOUT = 0x03,
+ TEEC_MEMREF_TEMP_INPUT = 0x05,
+ TEEC_MEMREF_TEMP_OUTPUT = 0x06,
+ TEEC_MEMREF_TEMP_INOUT = 0x07,
+ TEEC_ION_INPUT = 0x08,
+ TEEC_ION_SGLIST_INPUT = 0x09,
+ TEEC_MEMREF_SHARED_INOUT = 0x0a,
+ TEEC_MEMREF_WHOLE = 0xc,
+ TEEC_MEMREF_PARTIAL_INPUT = 0xd,
+ TEEC_MEMREF_PARTIAL_OUTPUT = 0xe,
+ TEEC_MEMREF_PARTIAL_INOUT = 0xf
+};
+
+enum TEE_ParamType {
+ TEE_PARAM_TYPE_NONE = 0x0,
+ TEE_PARAM_TYPE_VALUE_INPUT = 0x1,
+ TEE_PARAM_TYPE_VALUE_OUTPUT = 0x2,
+ TEE_PARAM_TYPE_VALUE_INOUT = 0x3,
+ TEE_PARAM_TYPE_MEMREF_INPUT = 0x5,
+ TEE_PARAM_TYPE_MEMREF_OUTPUT = 0x6,
+ TEE_PARAM_TYPE_MEMREF_INOUT = 0x7,
+ TEE_PARAM_TYPE_ION_INPUT = 0x8,
+ TEE_PARAM_TYPE_ION_SGLIST_INPUT = 0x9,
+ TEE_PARAM_TYPE_MEMREF_SHARED_INOUT = 0x0a,
+ TEE_PARAM_TYPE_RESMEM_INPUT = 0xc,
+ TEE_PARAM_TYPE_RESMEM_OUTPUT = 0xd,
+ TEE_PARAM_TYPE_RESMEM_INOUT = 0xe
+};
+
+enum TEEC_LoginMethod {
+ TEEC_LOGIN_PUBLIC = 0x0,
+ TEEC_LOGIN_USER,
+ TEEC_LOGIN_GROUP,
+ TEEC_LOGIN_APPLICATION = 0x4,
+ TEEC_LOGIN_USER_APPLICATION = 0x5,
+ TEEC_LOGIN_GROUP_APPLICATION = 0x6,
+ TEEC_LOGIN_IDENTIFY = 0x7,
+ TEEK_LOGIN_IDENTIFY = 0x80000001,
+};
+
+/* Add event id's name in 'view_state[]' in same order */
+enum tee_event_id {
+ INVOKE_CMD_START,
+ INVOKE_CMD_END,
+ SMC_SEND,
+ SMC_DONE,
+ SMC_IN,
+ SMC_OUT,
+ SMC_SLEEP,
+ SMC_PREEMPT,
+ GTASK_GET_CMD,
+ GTASK_PUT_CMD,
+ GTASK_REQ_TA,
+ GTASK_RESP_TA,
+ SPI_WAKEUP,
+ SCHED_IN,
+ SCHED_OUT,
+ INTERRUPT_HANDLE_SPI_START,
+ INTERRUPT_HANDLE_SPI_REE_RESPONSE,
+ INTERRUPT_HANDLE_SPI_REE_MISS,
+ INTERRUPT_HANDLE_SPI_REE_SCHEDULED,
+ INTERRUPT_HANDLE_SPI_END,
+ INTERRUPT_HANDLE_START,
+ INTERRUPT_HANDLE_END,
+ TEE_EVENT_MAX
+};
+
+#define TZ_WQ_MAX_ACTIVE 1
+#endif
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/inc/teek_ns_client.h b/trustzone-awared-vm/vm/vtzdriver/inc/teek_ns_client.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a6c008523657d20a9638bedccb3260699c78fd7
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/inc/teek_ns_client.h
@@ -0,0 +1,256 @@
+/*
+ * teek_ns_client.h
+ *
+ * define structures and IOCTLs.
+ *
+ * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef TEEK_NS_CLIENT_H
+#define TEEK_NS_CLIENT_H
+
+#include
+#include
+#include
+#include
+#include "tc_ns_client.h"
+#include "tc_ns_log.h"
+
+#define TC_NS_CLIENT_IOC_MAGIC 't'
+#define TC_NS_CLIENT_DEV "tc_ns_client"
+#define TC_PRIV_DEV "tc_private"
+#define TC_NS_CVM_DEV "tc_ns_cvm"
+#define TC_NS_CLIENT_DEV_NAME "/dev/tc_ns_client"
+
+#define EXCEPTION_MEM_SIZE (8*1024) /* mem for exception handling */
+
+#define TSP_REQUEST 0xB2000008
+#define TSP_RESPONSE 0xB2000009
+
+#define TSP_REE_SIQ 0xB200000A
+#define TSP_CRASH 0xB200000B
+
+#ifdef CONFIG_TEE_UPGRADE
+#define TSP_REBOOT 0xB2000012
+#define TSP_CPU_ON 0xB2000013
+#define TSP_REBOOT_DONE 0xB2000015
+#else
+#define TSP_REBOOT 0xB200000E
+#define TSP_CPU_ON 0xB200000F
+#define TSP_REBOOT_DONE 0xB2000010
+#endif
+
+#define TSP_PREEMPTED 0xB2000005
+#define TC_CALL_GLOBAL 0x01
+#define TC_CALL_SYNC 0x02
+#define TC_CALL_LOGIN 0x04
+#define TEE_REQ_FROM_USER_MODE 0U
+#define TEE_REQ_FROM_KERNEL_MODE 1U
+#define TEE_PARAM_NUM 4
+#define VMALLOC_TYPE 0
+#define RESERVED_TYPE 1
+
+/* Max sizes for login info buffer comming from teecd */
+#define MAX_PACKAGE_NAME_LEN 255
+/* The apk certificate format is as follows:
+ * modulus_size(4 bytes) + modulus buffer(512 bytes)
+ * + exponent size(4 bytes) + exponent buffer(1 bytes)
+ */
+#define MAX_PUBKEY_LEN 1024
+
+struct tc_ns_dev_list {
+ struct mutex dev_lock; /* for dev_file_list */
+ struct list_head dev_file_list;
+};
+
+struct tc_uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t timehi_and_version;
+ uint8_t clockseq_and_node[8]; /* clock len is 8 */
+};
+
+#define INVALID_MAP_ADDR ((void*)-1)
+struct tc_ns_shared_mem {
+ void *kernel_addr;
+ void *user_addr;
+ void *user_addr_ca; /* for ca alloc share mem */
+ unsigned int len;
+ int mem_type;
+ struct list_head head;
+ atomic_t usage;
+ atomic_t offset;
+};
+
+struct tc_ns_service {
+ unsigned char uuid[UUID_LEN];
+ struct mutex session_lock; /* for session_list */
+ struct list_head session_list;
+ struct list_head head;
+ struct mutex operation_lock; /* for session's open/close */
+ atomic_t usage;
+ unsigned int nsid;
+};
+
+#define SERVICES_MAX_COUNT 32 /* service limit can opened on 1 fd */
+struct tc_ns_dev_file {
+ unsigned int dev_file_id;
+ struct mutex service_lock; /* for service_ref[], services[] */
+ uint8_t service_ref[SERVICES_MAX_COUNT]; /* a judge if set services[i]=NULL */
+ struct tc_ns_service *services[SERVICES_MAX_COUNT];
+ struct mutex shared_mem_lock; /* for shared_mem_list */
+ struct list_head shared_mem_list;
+ struct list_head head;
+ /* Device is linked to call from kernel */
+ uint8_t kernel_api;
+ /* client login info provided by teecd, can be either package name and public
+ * key or uid(for non android services/daemons)
+ * login information can only be set once, dont' allow subsequent calls
+ */
+ bool login_setup;
+ struct mutex login_setup_lock; /* for login_setup */
+#ifdef CONFIG_AUTH_HASH
+ bool cainfo_hash_setup;
+ struct mutex cainfo_hash_setup_lock;
+#endif
+ uint32_t pkg_name_len;
+ uint8_t pkg_name[MAX_PACKAGE_NAME_LEN];
+ uint32_t pub_key_len;
+ uint8_t pub_key[MAX_PUBKEY_LEN];
+ int load_app_flag;
+#ifdef CONFIG_CONFIDENTIAL_CONTAINER
+ uint32_t nsid;
+#endif
+ struct completion close_comp; /* for kthread close unclosed session */
+#ifdef CONFIG_TEE_TELEPORT_SUPPORT
+ bool portal_enabled;
+#endif
+};
+
+union tc_ns_parameter {
+ struct {
+ unsigned int buffer;
+ unsigned int size;
+ } memref;
+ struct {
+ unsigned int a;
+ unsigned int b;
+ } value;
+};
+
+struct tc_ns_login {
+ unsigned int method;
+ unsigned int mdata;
+};
+
+struct tc_ns_operation {
+ unsigned int paramtypes;
+ union tc_ns_parameter params[TEE_PARAM_NUM];
+ unsigned int buffer_h_addr[TEE_PARAM_NUM];
+ struct tc_ns_shared_mem *sharemem[TEE_PARAM_NUM];
+ void *mb_buffer[TEE_PARAM_NUM];
+};
+
+struct tc_ns_temp_buf {
+ void *temp_buffer;
+ unsigned int size;
+};
+
+enum smc_cmd_type {
+ CMD_TYPE_GLOBAL,
+ CMD_TYPE_TA,
+ CMD_TYPE_TA_AGENT,
+ CMD_TYPE_TA2TA_AGENT, /* compatible with TA2TA2TA->AGENT etc. */
+ CMD_TYPE_BUILDIN_AGENT,
+ CMD_TYPE_RELEASE_AGENT, /* only for release agent */
+};
+
+struct tc_ns_smc_cmd {
+ uint8_t uuid[sizeof(struct tc_uuid)];
+ unsigned int cmd_type;
+ unsigned int cmd_id;
+ unsigned int dev_file_id;
+ unsigned int context_id;
+ unsigned int agent_id;
+ unsigned int operation_phys;
+ unsigned int operation_h_phys;
+ unsigned int login_method;
+ unsigned int login_data_phy;
+ unsigned int login_data_h_addr;
+ unsigned int login_data_len;
+ unsigned int err_origin;
+ int ret_val;
+ unsigned int event_nr;
+ unsigned int uid;
+ unsigned int ca_pid; /* pid */
+ unsigned int pid; /* tgid */
+ unsigned int nsid;
+ unsigned int eventindex; /* tee audit event index for upload */
+ bool started;
+} __attribute__((__packed__));
+
+/*
+ * @brief
+ */
+struct tc_wait_data {
+ wait_queue_head_t send_cmd_wq;
+ int send_wait_flag;
+};
+
+#define NUM_OF_SO 1
+#ifdef CONFIG_CMS_CAHASH_AUTH
+#define KIND_OF_SO 1
+#else
+#define KIND_OF_SO 2
+#endif
+struct tc_ns_session {
+ unsigned int session_id;
+ struct list_head head;
+ struct tc_wait_data wait_data;
+ struct mutex ta_session_lock; /* for open/close/invoke on 1 session */
+ struct tc_ns_dev_file *owner;
+ uint8_t auth_hash_buf[MAX_SHA_256_SZ * NUM_OF_SO + MAX_SHA_256_SZ];
+ atomic_t usage;
+};
+
+struct mb_cmd_pack {
+ struct tc_ns_operation operation;
+ unsigned char login_data[MAX_SHA_256_SZ * NUM_OF_SO + MAX_SHA_256_SZ];
+};
+
+struct load_img_params {
+ struct tc_ns_dev_file *dev_file;
+ const char *file_buffer;
+ unsigned int file_size;
+ struct mb_cmd_pack *mb_pack;
+ char *mb_load_mem;
+ struct tc_uuid *uuid_return;
+ unsigned int mb_load_size;
+};
+
+struct tc_call_params {
+ struct tc_ns_dev_file *dev;
+ struct tc_ns_client_context *context;
+ struct tc_ns_session *sess;
+ uint8_t flags;
+};
+
+struct tc_op_params {
+ struct mb_cmd_pack *mb_pack;
+ struct tc_ns_smc_cmd *smc_cmd;
+ struct tc_ns_temp_buf local_tmpbuf[TEE_PARAM_NUM];
+ uint32_t trans_paramtype[TEE_PARAM_NUM];
+ bool op_inited;
+};
+
+#endif
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/vtzf.c b/trustzone-awared-vm/vm/vtzdriver/vtzf.c
new file mode 100644
index 0000000000000000000000000000000000000000..08851dfb7492bf87772b3ea93611069ec3908b1a
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/vtzf.c
@@ -0,0 +1,2126 @@
+#include
+#include
+#include
+#include
+// #include
+#include
+// #include
+#include
+#include
+// #include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "vtzf.h"
+
+#include "securec.h"
+#include "tc_ns_client.h"
+#include "tc_ns_log.h"
+#include "teek_client_constants.h"
+
+
+#define CONFIG_CONFIDENTIAL_CONTAINER
+
+#define PRINTF_SIZE 16
+void dump_buff(const char* buffer, size_t bufLen) {
+ size_t i;
+ if (buffer == NULL || bufLen == 0) {
+ return;
+ }
+
+ // printf("\n--------------------------------------------------\n");
+ tlogd("--------------------------------------------------\n");
+ tlogd("bufLen = %d\n", (int)bufLen);
+ for (i = 0; i < bufLen; i++) {
+ if (i % PRINTF_SIZE == 0 && i != 0) {
+ tlogd("\n");
+ }
+ tlogd("%02x ", *(buffer + i));
+ }
+ tlogd("\n--------------------------------------------------\n");
+ return;
+}
+
+struct mutex g_seq_lock;
+uint32_t g_seq_num;
+static struct class *g_driver_class;
+static struct device_node *g_dev_node;
+
+struct dev_node g_tc_client;
+struct dev_node g_tc_private;
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+struct dev_node g_tc_cvm;
+#endif
+/* dev node list and itself has mutex to avoid race */
+struct vtzf_dev_list g_tc_ns_dev_list;
+struct vtzf_serial_port_list g_serial_port_list;
+
+static unsigned int g_device_file_cnt = 1;
+static DEFINE_MUTEX(g_device_file_cnt_lock);
+
+static struct vm_operations_struct g_shared_remap_vm_ops = {
+ .open = shared_vma_open,
+ .close = shared_vma_close,
+};
+
+
+static const struct file_operations g_tc_ns_client_fops = {
+ .owner = THIS_MODULE,
+ .open = vtzf_client_open,
+ .release = vtzf_close,
+ .unlocked_ioctl = tc_client_ioctl,
+ .mmap = vtzf_mmap,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tc_compat_client_ioctl,
+#endif
+};
+
+static const struct file_operations g_teecd_fops = {
+ .owner = THIS_MODULE,
+ .open = vtzf_private_open,
+ .release = vtzf_close,
+ .unlocked_ioctl = tc_private_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tc_compat_private_ioctl,
+#endif
+};
+
+static const struct file_operations g_cvm_fops = {
+ .owner = THIS_MODULE,
+ .open = vtzf_cvm_open,
+ .release = vtzf_close,
+ .unlocked_ioctl = tc_cvm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = tc_compat_cvm_ioctl,
+#endif
+};
+
+const struct file_operations *get_cvm_fops(void)
+{
+ return &g_cvm_fops;
+}
+
+struct vtzf_dev_list *get_dev_list(void)
+{
+ return &g_tc_ns_dev_list;
+}
+
+struct vtzf_serial_port_list *get_serial_port_list(void)
+{
+ return &g_serial_port_list;
+}
+
+static uint32_t get_seq_num(void)
+{
+ uint32_t ret;
+ mutex_lock(&g_seq_lock);
+ g_seq_num = (g_seq_num + 2) % 65536;
+ ret = g_seq_num;
+ mutex_unlock(&g_seq_lock);
+ return ret;
+}
+
+static int create_dev_node(struct dev_node *node)
+{
+ int ret;
+ if (!node || !(node->node_name)) {
+ tloge("node or member is null\n");
+ return -EFAULT;
+ }
+ if (alloc_chrdev_region(&(node->devt), 0, 1,
+ node->node_name) != 0) {
+ tloge("alloc chrdev region failed");
+ ret = -EFAULT;
+ return ret;
+ }
+ node->class_dev = device_create(node->driver_class, NULL, node->devt,
+ NULL, node->node_name);
+ if (IS_ERR_OR_NULL(node->class_dev)) {
+ tloge("class device create failed");
+ ret = -ENOMEM;
+ goto chrdev_region_unregister;
+ }
+ node->class_dev->of_node = g_dev_node;
+
+ cdev_init(&(node->char_dev), node->fops);
+ (node->char_dev).owner = THIS_MODULE;
+
+ return 0;
+
+chrdev_region_unregister:
+ unregister_chrdev_region(node->devt, 1);
+ return ret;
+}
+
+static int init_dev_node(struct dev_node *node, char *node_name,
+ struct class *driver_class, const struct file_operations *fops)
+{
+ int ret = -1;
+ if (!node) {
+ tloge("node is NULL\n");
+ return ret;
+ }
+ node->node_name = node_name;
+ node->driver_class = driver_class;
+ node->fops = fops;
+
+ ret = create_dev_node(node);
+ return ret;
+}
+
+static void destory_dev_node(struct dev_node *node, struct class *driver_class)
+{
+ device_destroy(driver_class, node->devt);
+ unregister_chrdev_region(node->devt, 1);
+ return;
+}
+
+static int tc_ns_client_init(void)
+{
+ int ret;
+
+ g_driver_class = class_create(THIS_MODULE, TC_NS_CLIENT_DEV);
+ if (IS_ERR_OR_NULL(g_driver_class)) {
+ tloge("class create failed");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ ret = init_dev_node(&g_tc_client, TC_NS_CLIENT_DEV, g_driver_class, &g_tc_ns_client_fops);
+ if (ret != 0) {
+ class_destroy(g_driver_class);
+ return ret;
+ }
+ ret = init_dev_node(&g_tc_private, TC_PRIV_DEV, g_driver_class, &g_teecd_fops);
+ if (ret != 0) {
+ destory_dev_node(&g_tc_client, g_driver_class);
+ class_destroy(g_driver_class);
+ return ret;
+ }
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ ret = init_dev_node(&g_tc_cvm, TC_NS_CVM_DEV, g_driver_class, get_cvm_fops());
+ if (ret != 0) {
+ destory_dev_node(&g_tc_private, g_driver_class);
+ destory_dev_node(&g_tc_client, g_driver_class);
+ class_destroy(g_driver_class);
+ return ret;
+ }
+#endif
+ INIT_LIST_HEAD(&g_tc_ns_dev_list.dev_file_list);
+ mutex_init(&g_tc_ns_dev_list.dev_lock);
+ return ret;
+}
+
+static int enable_dev_nodes(void)
+{
+ int ret;
+
+ ret = cdev_add(&(g_tc_private.char_dev),
+ MKDEV(MAJOR(g_tc_private.devt), 0), 1);
+ if (ret < 0) {
+ tloge("cdev add failed %d", ret);
+ return ret;
+ }
+
+ ret = cdev_add(&(g_tc_client.char_dev),
+ MKDEV(MAJOR(g_tc_client.devt), 0), 1);
+ if (ret < 0) {
+ tloge("cdev add failed %d", ret);
+ cdev_del(&(g_tc_private.char_dev));
+ return ret;
+ }
+
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ ret = cdev_add(&(g_tc_cvm.char_dev),
+ MKDEV(MAJOR(g_tc_cvm.devt), 0), 1);
+ if (ret < 0) {
+ tloge("cdev add failed %d", ret);
+ cdev_del(&(g_tc_client.char_dev));
+ cdev_del(&(g_tc_private.char_dev));
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+static void free_serial_port_list(void)
+{
+ struct vtzf_serial_port_file *dev_file = NULL, *temp = NULL;
+
+ mutex_lock(&g_serial_port_list.lock);
+ list_for_each_entry_safe(dev_file, temp, &g_serial_port_list.head, head) {
+ list_del(&dev_file->head);
+ if (dev_file->filep) {
+ filp_close(dev_file->filep, NULL);
+ }
+ if (dev_file->buffer) {
+ kfree(dev_file->buffer);
+ }
+ mutex_destroy(&dev_file->lock);
+ kfree(dev_file);
+ }
+ mutex_unlock(&g_serial_port_list.lock);
+}
+
+static int serial_port_init(void)
+{
+ int ret = 0;
+ int i;
+ int size_written;
+ struct file *file;
+ struct vtzf_serial_port_file *serial_port_file = NULL;
+ void *buffer = NULL;
+ char device_path[256];// = "/dev/virtio-ports/vtzf_serialport1";
+ INIT_LIST_HEAD(&g_serial_port_list.head);
+ mutex_init(&g_serial_port_list.lock);
+
+ for(i=0;i < SERIAL_PORT_NUM;i++) {
+ size_written = snprintf(device_path, sizeof(device_path), "%s%d", VTZF_SERIALPORT, i);
+
+ serial_port_file = kzalloc(sizeof(*serial_port_file), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)serial_port_file)) {
+ tloge("alloc serial_port_file failed\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+ buffer = kzalloc(SERIAL_PORT_BUF_LEN, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) {
+ tloge("alloc serial_port_file failed\n");
+ ret = -ENOMEM;
+ kfree(serial_port_file);
+ goto err;
+ }
+ // 打开设备文件
+ file = filp_open(device_path, O_RDWR, 0);
+ if (IS_ERR(file)) {
+ tloge("open serial_pore failed \n");
+ ret = -EFAULT;
+ kfree(serial_port_file);
+ kfree(buffer);
+ goto err;
+ }
+ serial_port_file->filep = file;
+ serial_port_file->buffer = buffer;
+ mutex_init(&serial_port_file->lock);
+ list_add_tail(&serial_port_file->head, &g_serial_port_list.head);
+ }
+ tlogd(" open serial success -----------\n");
+ return 0;
+err:
+ mutex_destroy(&g_serial_port_list.lock);
+ free_serial_port_list();
+ return ret;
+}
+
+static void seq_num_init(void)
+{
+ mutex_init(&g_seq_lock);
+ g_seq_num = 0;
+}
+
+/*
+static void tc_re_init(const struct device *class_dev)
+{
+ int ret;
+ //agent_init();
+ //ret = tc_ns_register_ion_mem();
+ //if (ret != 0)
+ // tloge("Failed to register ion mem in tee\n");
+#ifdef CONFIG_TZDRIVER_MODULE
+ ret = init_tlogger_service();
+ if (ret != 0)
+ tloge("tlogger init failed\n");
+#endif
+}
+*/
+static int __init vtzf_init(void)
+{
+ int ret;
+ ret = tc_ns_client_init();
+ if (ret != 0)
+ return ret;
+
+ //tlogcat 相关
+ //tc_re_init(g_tc_client.class_dev);
+
+ ret = enable_dev_nodes();
+ if (ret != 0) {
+ tloge("enable dev nodes failed\n");
+ goto class_device_destroy;
+ }
+ ret = serial_port_init();
+ if (ret != 0) {
+ goto class_device_destroy;
+ }
+ seq_num_init();
+ return 0;
+
+class_device_destroy:
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ destory_dev_node(&g_tc_cvm, g_driver_class);
+#endif
+ destory_dev_node(&g_tc_client, g_driver_class);
+ destory_dev_node(&g_tc_private, g_driver_class);
+ class_destroy(g_driver_class);
+ //platform_driver_unregister(&g_tz_platform_driver);
+ return ret;
+}
+
+static void free_dev_list(void)
+{
+ struct vtzf_dev_file *dev_file = NULL, *temp = NULL;
+
+ mutex_lock(&g_tc_ns_dev_list.dev_lock);
+ list_for_each_entry_safe(dev_file, temp, &g_tc_ns_dev_list.dev_file_list, head) {
+ list_del(&dev_file->head);
+ kfree(dev_file);
+ }
+ mutex_unlock(&g_tc_ns_dev_list.dev_lock);
+}
+
+static void __exit vtzf_exit(void)
+{
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ cdev_del(&(g_tc_cvm.char_dev));
+#endif
+ cdev_del(&(g_tc_private.char_dev));
+ cdev_del(&(g_tc_client.char_dev));
+#if defined(CONFIG_CONFIDENTIAL_CONTAINER) || defined(CONFIG_TEE_TELEPORT_SUPPORT)
+ destory_dev_node(&g_tc_cvm, g_driver_class);
+#endif
+
+ destory_dev_node(&g_tc_client, g_driver_class);
+ destory_dev_node(&g_tc_private, g_driver_class);
+ class_destroy(g_driver_class);
+ //free_all_session();
+ free_dev_list();
+ free_serial_port_list();
+}
+
+int tc_ns_client_open(struct vtzf_dev_file **dev_file, uint32_t flag)
+{
+ struct vtzf_dev_file *dev = NULL;
+ tlogd("vtzf open \n");
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)dev)) {
+ tloge("vtzf_dev_file malloc failed\n");
+ return -ENOMEM;
+ }
+
+ mutex_lock(&g_tc_ns_dev_list.dev_lock);
+ list_add_tail(&dev->head, &g_tc_ns_dev_list.dev_file_list);
+ mutex_unlock(&g_tc_ns_dev_list.dev_lock);
+
+ mutex_lock(&g_device_file_cnt_lock);
+ dev->dev_file_id = g_device_file_cnt;
+ g_device_file_cnt++;
+ mutex_unlock(&g_device_file_cnt_lock);
+
+ INIT_LIST_HEAD(&dev->shared_mem_list);
+
+ mutex_init(&dev->shared_mem_lock);
+
+ (void)open_tzdriver(dev, flag);
+ /* Once this device is opened, Tzdriver must be opened accordingly */
+
+ *dev_file = dev;
+ return 0;
+}
+
+static int vtzf_client_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ struct vtzf_dev_file *dev_file = NULL;
+ (void)inode;
+ file->private_data = NULL;
+ ret = tc_ns_client_open(&dev_file, TC_NS_CLIENT_DEV_FLAG);
+ if (!ret)
+ file->private_data = dev_file;
+
+ return 0;
+}
+
+static int vtzf_private_open(struct inode *inode, struct file *file)
+{
+ struct vtzf_dev_file *dev_file = NULL;
+
+ tlogd("vtzf open \n");
+
+ dev_file = kzalloc(sizeof(*dev_file), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)dev_file)) {
+ tloge("vtzf_dev_file malloc failed\n");
+ return -ENOMEM;
+ }
+
+ mutex_lock(&g_tc_ns_dev_list.dev_lock);
+ list_add_tail(&dev_file->head, &g_tc_ns_dev_list.dev_file_list);
+ mutex_unlock(&g_tc_ns_dev_list.dev_lock);
+
+ mutex_lock(&g_device_file_cnt_lock);
+ dev_file->dev_file_id = g_device_file_cnt;
+ g_device_file_cnt++;
+ mutex_unlock(&g_device_file_cnt_lock);
+
+ INIT_LIST_HEAD(&dev_file->shared_mem_list);
+
+ mutex_init(&dev_file->shared_mem_lock);
+
+ file->private_data = dev_file;
+
+ (void)open_tzdriver(dev_file, TC_PRIVATE_DEV_FLAG);
+ /* Once this device is opened, Tzdriver must be opened accordingly */
+
+ return 0;
+}
+
+static int vtzf_cvm_open(struct inode *inode, struct file *file)
+{
+ int ret = -1;
+ struct vtzf_dev_file *dev = NULL;
+ (void)inode;
+
+#ifdef CONFIG_TEE_TELEPORT_AUTH
+ ret = check_tee_teleport_auth();
+#endif
+#ifdef CONFIG_TEE_AGENTD_AUTH
+ if (ret != 0)
+ ret = check_tee_agentd_auth();
+#endif
+ //if (ret != 0) {
+ // tloge("teleport/agentd auth failed, ret %d\n", ret);
+ // return -EACCES;
+ //}
+
+ file->private_data = NULL;
+ ret = tc_ns_client_open(&dev, TC_CVM_DEV_FLAG);
+ if (ret == 0)
+ file->private_data = dev;
+ return ret;
+}
+
+static int open_tzdriver(struct vtzf_dev_file *dev_file, uint32_t flag)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_open_tzd packet_cmd;
+ struct_packet_rsp_open_tzd packet_rsp;
+
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ dev_file->ptzfd = -1;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_OPEN_TZD;
+ packet_cmd.vmid = 0;
+ /* if flag==0, open tc_ns_client; if flag==1, open tc_private */
+ packet_cmd.flag = flag;
+
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ if (ret) {
+ tloge("open TZdriver failed ret is %d\n", ret);
+ goto END;
+ }
+ dev_file->ptzfd = packet_rsp.ptzfd;
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+
+END:
+ return ret;
+}
+
+int vtzf_close(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+ struct vtzf_dev_file *dev_file = file->private_data;
+
+ mutex_destroy(&dev_file->shared_mem_lock);
+
+ mutex_lock(&g_tc_ns_dev_list.dev_lock);
+ list_del(&dev_file->head);
+ mutex_unlock(&g_tc_ns_dev_list.dev_lock);
+ /* 这里应该给Proxy发送消息close对应的TZdriver */
+ (void)close_tzdriver(dev_file);
+
+
+ if (memset_s(dev_file, sizeof(*dev_file), 0, sizeof(*dev_file)))
+ tloge("memset_s dev file fail \n");
+ kfree(dev_file);
+// 在这里把dev_file之前分配的空间清理一下?先给Proxy发送关闭的消息再释放免得下面访问VM被释放的内存而崩溃
+ mutex_lock(&g_device_file_cnt_lock);
+ g_device_file_cnt--;
+ mutex_unlock(&g_device_file_cnt_lock);
+
+ file->private_data = NULL;
+
+ return ret;
+}
+
+static int close_tzdriver(struct vtzf_dev_file *dev_file)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_close_tzd packet_cmd;
+ struct_packet_rsp_close_tzd packet_rsp;
+
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+ if (dev_file->ptzfd <= 0) {
+ tlogd("The TZdriver on the host has not been opened yet\n");
+ return 0;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_CLOSE_TZD;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ tlogd("close ptzfd = %d\n", dev_file->ptzfd);
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ if (ret) {
+ tloge("close TZdriver failed ret is %d\n", ret);
+ goto END;
+ }
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+END:
+ return ret;
+}
+
+void shared_vma_open(struct vm_area_struct *vma)
+{
+ (void)vma;
+}
+
+void shared_vma_close(struct vm_area_struct *vma)
+{
+ struct vtzf_dev_file *dev_file = NULL;
+ struct vtzf_shared_mem *shared_mem = NULL;
+ struct vtzf_shared_mem *shared_mem_temp = NULL;
+ bool find = false;
+ uintptr_t user_addr = NULL;
+
+
+ if (!vma) {
+ tloge("virtual memory area is null \n");
+ return;
+ }
+ dev_file = vma->vm_private_data;
+ if (!dev_file) {
+ tloge("virtual memory area private data is null \n");
+ return;
+ }
+
+ mutex_lock(&dev_file->shared_mem_lock);
+ list_for_each_entry_safe(shared_mem, shared_mem_temp,
+ &dev_file->shared_mem_list, head) {
+ if (shared_mem) {
+ if (shared_mem->user_virt_addr ==
+ (void *)(uintptr_t)vma->vm_start) {
+ shared_mem->user_virt_addr = NULL;
+ list_del(&shared_mem->head);
+
+ if (shared_mem->kernel_virt_addr) {
+
+ kfree(shared_mem->kernel_virt_addr);
+ shared_mem->kernel_virt_addr = NULL;
+ }
+ kfree(shared_mem);
+ find = true;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&dev_file->shared_mem_lock);
+ if (find) {
+ (void)proxy_mmap(dev_file, (void *)(uintptr_t)vma->vm_start, 0 ,0, true);
+ }
+}
+
+static int proxy_mmap(struct vtzf_dev_file *dev_file,
+ void * user_buffer, uint32_t buffer_size,
+ uint32_t pgoff, uint8_t unmap)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_mmap packet_cmd;
+ struct_packet_rsp_mmap packet_rsp;
+
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.cmd = unmap ? VTZF_MUNMAP : VTZF_MMAP;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ packet_cmd.buffer = (uint64_t)user_buffer;
+ packet_cmd.size = buffer_size;
+ packet_cmd.offset = pgoff;
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ }
+END:
+ return ret;
+}
+
+static int vtzf_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct vtzf_dev_file *dev_file = NULL;
+ struct vtzf_shared_mem *shared_mem = NULL;
+ void *addr = NULL;
+ size_t len;
+
+ if (!filp || !vma || !filp->private_data) {
+ tloge("vtzf invalid args for mmap \n");
+ return -EINVAL;
+ }
+ dev_file = filp->private_data;
+
+ shared_mem = kmalloc(sizeof(*shared_mem), GFP_KERNEL | __GFP_ZERO);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)shared_mem)) {
+ tloge("vtzf shared_mem kmalloc failed \n");
+ return -ENOMEM;
+ }
+
+ len = vma->vm_end - vma->vm_start;
+ len = ALIGN(len, SZ_4K);
+ if (len > MAILBOX_POOL_SIZE) {
+ tloge("vtzf alloc sharemem buffer size %zu is too large \n", len);
+ kfree(shared_mem);
+ return -EINVAL;
+ }
+
+ addr = kmalloc(len, GFP_KERNEL | __GFP_ZERO);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)addr)) {
+ tloge("kmalloc shared_mem buffer failed \n");
+ return -ENOMEM;
+ }
+
+ shared_mem->kernel_virt_addr = addr;
+ shared_mem->len = len;
+ shared_mem->user_virt_addr =(void *)vma->vm_start;
+ shared_mem->phy_addr = (void *)virt_to_phys(addr);
+
+ tlogv("shared_mem user virtual address = 0x%016llx \n", (uint64_t)shared_mem->user_virt_addr);
+ tlogv("shared_mem kernel virtual address = 0x%016llx \n", (uint64_t)shared_mem->kernel_virt_addr);
+ tlogv("shared_mem physical address = 0x%016llx \n", (uint64_t)shared_mem->phy_addr);
+ tlogv("shared_mem allocated buffer len = 0x%08x, %d \n", (int)len, (int)len);
+
+ vma->vm_flags |= VM_USERMAP;
+
+ if (remap_pfn_range(vma, vma->vm_start,
+ virt_to_phys(addr)>>PAGE_SHIFT, len, vma->vm_page_prot)) {
+ tloge("shared_mem buffer remap failed \n");
+ return -EAGAIN;
+ }
+
+ vma->vm_flags |= VM_DONTCOPY;
+ vma->vm_ops = &g_shared_remap_vm_ops;
+ shared_vma_open(vma);
+ vma->vm_private_data = (void *)dev_file;
+
+ shared_mem->user_virt_addr = (void *)(uintptr_t)vma->vm_start;
+ atomic_set(&shared_mem->offset, vma->vm_pgoff);
+ mutex_lock(&dev_file->shared_mem_lock);
+ list_add_tail(&shared_mem->head, &dev_file->shared_mem_list);
+ mutex_unlock(&dev_file->shared_mem_lock);
+ tlogd("************ offset *************\n ");
+ tlogd(" = %lu \n", (unsigned long)atomic_read(&shared_mem->offset));
+ /* proxy 对应mmap */
+ (void)proxy_mmap(filp->private_data, shared_mem->user_virt_addr,
+ shared_mem->len, (uint32_t)atomic_read(&shared_mem->offset), false);
+
+ return 0;
+}
+
+static struct vtzf_serial_port_file *alloc_serial_port(void)
+{
+ struct vtzf_serial_port_file *dev_file = NULL;
+
+ while(1){
+ mutex_lock(&g_serial_port_list.lock);
+ list_for_each_entry(dev_file, &g_serial_port_list.head, head) {
+ if (dev_file->using == false) {
+ mutex_lock(&dev_file->lock);
+ dev_file->using = true;
+ tlogi(" alloc serial port \n");
+ mutex_unlock(&g_serial_port_list.lock);
+ return dev_file;
+ }
+ }
+ mutex_unlock(&g_serial_port_list.lock);
+ }
+ return NULL;
+}
+
+static void free_serial_port(struct vtzf_serial_port_file *file, ssize_t ssize_ret)
+{
+ if (file){
+ file->using = false;
+ tlogi(" free serial port \n");
+ mutex_unlock(&file->lock);
+ }
+ if (ssize_ret<=0){
+ tloge(" ------------Unexpected exit of user program serial_port free--------------- \n");
+ }
+}
+
+static long vtzf_ser_test(struct file *file, unsigned int cmd, void *argp)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ int ioctl_args;
+ struct_packet_cmd_test packet_cmd;
+ struct_packet_rsp_test packet_rsp;
+
+ if (copy_from_user(&ioctl_args, argp, sizeof(int))) {
+ tloge("copy ioctl_args_opensession from user failed \n");
+ ret = -ENOMEM;
+ return ret;
+ }
+ if (ioctl_args == 1) {
+ ;
+ } else if(ioctl_args == 2) {
+ packet_cmd.cmd = 618;
+ packet_cmd.seq_num = seq_num;
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (ret) {
+ return ret;
+ }
+ tlogd(" packet_rsp.seq_num =%d \n", packet_rsp.seq_num);
+ tlogd(" packet_rsp.ret =%d \n", packet_rsp.ret);
+ if(copy_to_user(argp, &(packet_rsp.ret) ,sizeof(int))){
+ ret = -EFAULT;
+ }
+ } else if (ioctl_args == 3){
+ packet_cmd.cmd = 520;
+ packet_cmd.seq_num = seq_num;
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (ret) {
+ return ret;
+ }
+ tlogd(" packet_rsp.seq_num =%d \n", packet_rsp.seq_num);
+ tlogd(" packet_rsp.ret =%d \n", packet_rsp.ret);
+ if(copy_to_user(argp, &(packet_rsp.ret) ,sizeof(int))){
+ ret = -EFAULT;
+ }
+ }
+ return ret;
+}
+
+
+#define INPUT 0
+#define OUTPUT 1
+#define INOUT 2
+
+static inline bool is_input_type(int dir)
+{
+ if (dir == INPUT || dir == INOUT)
+ return true;
+
+ return false;
+}
+
+static inline bool is_output_type(int dir)
+{
+ if (dir == OUTPUT || dir == INOUT)
+ return true;
+
+ return false;
+}
+
+static inline bool teec_value_type(unsigned int type, int dir)
+{
+ return ((is_input_type(dir) && type == TEEC_VALUE_INPUT) ||
+ (is_output_type(dir) && type == TEEC_VALUE_OUTPUT) ||
+ type == TEEC_VALUE_INOUT) ? true : false;
+}
+
+static inline bool teec_tmpmem_type(unsigned int type, int dir)
+{
+ return ((is_input_type(dir) && type == TEEC_MEMREF_TEMP_INPUT) ||
+ (is_output_type(dir) && type == TEEC_MEMREF_TEMP_OUTPUT) ||
+ type == TEEC_MEMREF_TEMP_INOUT) ? true : false;
+}
+
+static inline bool teec_memref_type(unsigned int type, int dir)
+{
+ return ((is_input_type(dir) && type == TEEC_MEMREF_PARTIAL_INPUT) ||
+ (is_output_type(dir) && type == TEEC_MEMREF_PARTIAL_OUTPUT) ||
+ type == TEEC_MEMREF_PARTIAL_INOUT) ? true : false;
+}
+
+static long tc_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
+
+ //handle_cmd_prepare(cmd);
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ:
+ case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ:
+ case TC_NS_CLIENT_IOCTL_SEND_CMD_REQ:
+ ret = tc_client_session_ioctl(file->private_data, cmd, arg);
+ break;
+ case TC_NS_CLIENT_IOCTL_CANCEL_CMD_REQ:
+ /* TZdriver don't support send cancel cmd now */
+ ret = tc_ns_send_cancel_cmd(file->private_data, argp);
+ break;
+ case TC_NS_CLIENT_IOCTL_LOGIN:
+ ret = tc_ns_client_login_func(file->private_data, argp);
+ break;
+ case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ:
+ ret = public_ioctl(file, cmd, arg, true);
+ break;
+ default:
+ tlogd(" default ----------------------------------\n");
+ ret =vtzf_ser_test(file, cmd, argp);
+ //ret = tc_client_agent_ioctl(file, cmd, arg);
+ break;
+ }
+
+ //handle_cmd_finish(cmd);
+
+ tlogd("tc client ioctl ret = 0x%x\n", ret);
+ return (long)ret;
+}
+
+int tc_ns_open_session(struct vtzf_dev_file *dev_file,
+ struct tc_ns_client_context *clicontext)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_session packet_cmd;
+ struct_packet_rsp_session packet_rsp;
+ size_t file_size;
+ char *buffer = NULL, *tmp_buffer = NULL;
+
+ if (!clicontext || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_OPEN_SESSION;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ tlogd(" sizeof(packet_cmd.cliContext) =%lu \n", sizeof(packet_cmd.cliContext));
+ packet_cmd.cliContext = *clicontext;
+ //if (copy_from_user(&(packet_cmd.cliContext), clicontext, sizeof(packet_cmd.cliContext) != 0)) {
+ // return -EFAULT;
+ //}
+ /* 有Buffer地址需要转换char *cliContext.file_buffer */
+ file_size = (size_t)packet_cmd.cliContext.file_size;
+ tlogd("file_size = %lu \n", file_size);
+ buffer = (char *)kzalloc(file_size, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) {
+ tloge("vtzf_dev_file malloc failed\n");
+ return -ENOMEM;
+ }
+ /* 保存原地址并返回给用户,libteec会释放这个地址 */
+ tmp_buffer = packet_cmd.cliContext.file_buffer;
+ tlogd("sizeof(char *) = %lu, sizeof(void*) =%lu ,sizeof(unsigned long) =%lu\n", sizeof(char *), sizeof(void*), sizeof(unsigned long));
+ tlogd("buffer addr = %016llx ,tmp_buffer =%016llx \n",
+ (unsigned long long)clicontext->file_buffer, (unsigned long long)tmp_buffer);
+ packet_cmd.cliContext.file_buffer = virt_to_phys(buffer);
+ //dump_buff((void *)(&packet_cmd.cliContext), sizeof(packet_cmd.cliContext));
+
+ /* 将image数据从用户拷贝到内核 */
+
+ if (copy_from_user(buffer, (const void __user *)tmp_buffer, file_size)) {
+ tloge("file buf get failed \n");
+ ret = -EFAULT;
+ goto END;
+ }
+ tlogd("------------image\n");
+ //dump_buff((void *)(buffer), 32);
+
+ tlogd("***** packet_cmd.cliContext.login.method = %u *****\n", packet_cmd.cliContext.login.method);
+
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ tlogd(" opensession ret =%d \n", ret);
+ if (ret) {
+ tloge("open session failed ret is %d\n", ret);
+ }
+ /* 还原地址,并将返回的内容拷贝回 */
+ packet_rsp.cliContext.file_buffer = tmp_buffer;
+ //if (copy_to_user(argp, &packet_rsp.cliContext, sizeof(struct tc_ns_client_context)) != 0){
+ // ret = -EFAULT;
+ //}
+ *clicontext = packet_rsp.cliContext;
+
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+END:
+ kfree(buffer);
+ return ret;
+}
+
+int tc_ns_close_session(struct vtzf_dev_file *dev_file, void __user *argp)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_session packet_cmd;
+ struct_packet_rsp_general packet_rsp;
+
+ if (!argp || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_CLOSE_SESSION;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+
+ if (copy_from_user(&packet_cmd.cliContext, argp, sizeof(packet_cmd.cliContext)) != 0) {
+ tloge("copy from user failed\n");
+ return -ENOMEM;
+ }
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ if (ret) {
+ tloge("close session failed ret is %d\n", ret);
+ }
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+
+ return ret;
+}
+
+static int alloc_for_tmp_mem(struct tc_ns_client_context *clicontext,
+ int index, uintptr_t addrs[][3])
+{
+ uintptr_t buf_size, buffer;
+ uintptr_t user_buf_size, user_buf;
+
+ buf_size = (uintptr_t)kzalloc(sizeof(uint32_t), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buf_size)) {
+ tloge("buf_size malloc failed\n");
+ return -ENOMEM;
+ }
+ user_buf = (uintptr_t)(clicontext->params[index].memref.buffer
+ | (uint64_t)clicontext->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM);
+ user_buf_size = (uintptr_t)(clicontext->params[index].memref.size_addr
+ | (uint64_t)clicontext->params[index].memref.size_h_addr << ADDR_TRANS_NUM);
+
+ /* 原bufsize是传的地址,这里把size从用户态拷贝下来,分配空间把地址传下去 */
+ if (copy_from_user((void *)buf_size, (void *)user_buf_size, sizeof(uint32_t)) != 0) {
+ tloge("copy from user failed\n");
+ kfree((void *)buf_size);
+ return -EFAULT;
+ }
+
+ tlogd(" buffer size = %u\n", *(uint32_t *)buf_size);
+
+ buffer = (uintptr_t)kzalloc(*(uint32_t *)buf_size, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) {
+ tloge("buffer malloc failed\n");
+ kfree((void *)buf_size);
+ return -ENOMEM;
+ }
+
+ /* 拷贝buffer数据 */
+ if (copy_from_user((void *)buffer, (void *)user_buf, *(uint32_t *)buf_size) != 0) {
+ tloge("copy from user failed\n");
+ kfree((void *)buf_size);
+ kfree((void *)buffer);
+ return -EFAULT;
+ }
+
+ /* 地址替换 */
+ addrs[index][0] = buf_size;
+ addrs[index][1] = buffer;
+ buf_size = (uintptr_t)virt_to_phys((void *)buf_size);
+ buffer = (uintptr_t)virt_to_phys((void *)buffer);
+ clicontext->params[index].memref.buffer = (unsigned int)(uintptr_t)buffer;
+ clicontext->params[index].memref.buffer_h_addr = ((unsigned long long)(uintptr_t)buffer) >> ADDR_TRANS_NUM;
+
+ clicontext->params[index].memref.size_addr = (unsigned int)(uintptr_t)buf_size;
+ clicontext->params[index].memref.size_h_addr = ((unsigned long long)(uintptr_t)buf_size) >> ADDR_TRANS_NUM;
+
+ return 0;
+}
+
+static int alloc_for_val_mem(struct tc_ns_client_context *clicontext,
+ int index, uintptr_t addrs[][3])
+{
+ uintptr_t val_a, val_b;
+ uintptr_t user_val_a, user_val_b;
+ val_a = (uintptr_t)kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)val_a)) {
+ tloge("val_a malloc failed\n");
+ return -ENOMEM;
+ }
+ val_b = val_a + sizeof(uint32_t);
+
+ user_val_a = (uintptr_t)(clicontext->params[index].value.a_addr
+ | (uint64_t)clicontext->params[index].value.a_h_addr << ADDR_TRANS_NUM);
+ user_val_b = (uintptr_t)(clicontext->params[index].value.b_addr
+ | (uint64_t)clicontext->params[index].value.b_h_addr << ADDR_TRANS_NUM);
+ /* 数据拷贝 */
+ if (copy_from_user((void *)val_a, (void *)user_val_a, sizeof(uint32_t)) != 0) {
+ tloge("copy from user failed\n");
+ kfree((void *)val_a);
+ return -EFAULT;
+ }
+ if (copy_from_user((void *)val_b, (void *)user_val_b, sizeof(uint32_t)) != 0) {
+ tloge("copy from user failed\n");
+ kfree((void *)val_a);
+ return -EFAULT;
+ }
+ /* 地址替换 */
+ addrs[index][0] = val_a;
+ addrs[index][1] = val_b;
+ val_a = (uintptr_t)virt_to_phys((void *)val_a);
+ val_b = (uintptr_t)virt_to_phys((void *)val_b);
+ clicontext->params[index].value.a_addr =
+ (unsigned int)(uintptr_t)val_a;
+ clicontext->params[index].value.a_h_addr =
+ ((unsigned long long)(uintptr_t)val_a) >> ADDR_TRANS_NUM;
+
+ clicontext->params[index].value.b_addr =
+ (unsigned int)(uintptr_t)val_b;
+ clicontext->params[index].value.b_h_addr =
+ ((unsigned long long)(uintptr_t)val_b) >> ADDR_TRANS_NUM;
+
+ return 0;
+}
+
+static int alloc_for_ref_mem(struct vtzf_dev_file *dev_file,
+ struct_packet_cmd_send_cmd *packet_cmd, int index, uintptr_t addrs[][3])
+{
+ uintptr_t size_addr, user_size_addr;
+ struct tc_ns_client_context *clicontext = &packet_cmd->cliContext;
+ bool b_found = false;
+ struct vtzf_shared_mem *shared_mem = NULL;
+ struct vtzf_shared_mem *shared_mem_temp = NULL;
+ void *user_buffer = NULL;
+ uintptr_t phy_buffer;
+
+ size_addr = (uintptr_t)kzalloc(sizeof(uint32_t), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)size_addr)) {
+ tloge("size_addr malloc failed\n");
+ return -ENOMEM;
+ }
+
+ user_size_addr = (uintptr_t)(clicontext->params[index].memref.size_addr
+ | (uint64_t)clicontext->params[index].memref.size_h_addr << ADDR_TRANS_NUM);
+ user_buffer = (void *)(clicontext->params[index].memref.buffer
+ | (uint64_t)clicontext->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM);
+
+ if (copy_from_user((void *)size_addr, (void *)user_size_addr, sizeof(uint32_t)) != 0) {
+ tloge("copy from user failed\n");
+ kfree((void *)size_addr);
+ return -EFAULT;
+ }
+
+ mutex_lock(&dev_file->shared_mem_lock);
+ list_for_each_entry_safe(shared_mem, shared_mem_temp, &dev_file->shared_mem_list, head) {
+ if (shared_mem) {
+ if (shared_mem->user_virt_addr == user_buffer) {
+ tlogv("found the mapped shared_mem for cliContext.params[index].memref.buffer\n");
+ phy_buffer = (uintptr_t)shared_mem->phy_addr;
+ clicontext->params[index].memref.buffer =
+ (unsigned int)(uintptr_t)phy_buffer;
+ clicontext->params[index].memref.buffer_h_addr =
+ ((unsigned long long)(uintptr_t)phy_buffer) >> ADDR_TRANS_NUM;
+
+ packet_cmd->addrs[index] = (unsigned long long)user_buffer;
+ b_found = true;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&dev_file->shared_mem_lock);
+ if (!b_found) {
+ kfree((void *)size_addr);
+ tloge("can't found the mapped shared_mem for cliContext.params[index].memref.buffer \n");
+ return -EFAULT;
+ }
+ addrs[index][0] = size_addr;
+ size_addr = (uintptr_t)virt_to_phys((void *)size_addr);
+ /* 地址替换 */
+ clicontext->params[index].memref.size_addr =
+ (unsigned int)(uintptr_t)size_addr;
+ clicontext->params[index].memref.size_h_addr =
+ ((unsigned long long)(uintptr_t)size_addr) >> ADDR_TRANS_NUM;
+
+ return 0;
+}
+/*
+static void transfer_shared_mem()
+{
+ void;
+}
+*/
+static int alloc_for_params(struct vtzf_dev_file *dev_file,
+ struct_packet_cmd_send_cmd *packet_cmd, uintptr_t addrs[][3])
+{
+ int ret;
+ int index;
+ uint32_t param_type;
+ bool checkValue;
+ for (index = 0; index < TEE_PARAM_NUM; index++) {
+ param_type = teec_param_type_get(packet_cmd->cliContext.param_types, index);
+ checkValue = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT);
+ tlogd("param %u type is %x\n", index, param_type);
+ if (teec_tmpmem_type(param_type, INOUT))
+ /* 分配空间,把数据从用户拷贝进来,将物理地址传下去 */
+ ret = alloc_for_tmp_mem(&packet_cmd->cliContext, index, addrs);
+
+ else if (teec_memref_type(param_type, INOUT))
+ /* mmap 已经分配过空间了,找到物理地址传下去*/
+ ret = alloc_for_ref_mem(dev_file , packet_cmd, index, addrs);
+
+ else if (teec_value_type(param_type, INOUT) || checkValue)
+ /* 分配空间,把数据从用户拷贝进来,将物理地址传下去 */
+ ret = alloc_for_val_mem(&packet_cmd->cliContext, index, addrs);
+ /*
+ else if (param_type == TEEC_MEMREF_SHARED_INOUT)
+
+ //ret = transfer_shared_mem();
+ */
+ else
+ tlogd("param type = TEEC_NONE\n");
+
+ if (ret != 0) {
+ goto ERR;
+ }
+ }
+
+ return 0;
+ERR:
+ /* 释放空间 */
+ return ret;
+
+}
+
+static void free_for_params(struct tc_ns_client_context *clicontext,
+ struct tc_ns_client_context *context, uintptr_t addrs[4][3])
+{
+ int ret = 0;
+ int index;
+ uint32_t param_type;
+ bool checkValue;
+ uintptr_t addr_a, addr_b;
+ uintptr_t user_addr_a, user_addr_b;
+
+ for (index = 0; index < TEE_PARAM_NUM; index++) {
+ param_type = teec_param_type_get(clicontext->param_types, index);
+ checkValue = (param_type == TEEC_ION_INPUT || param_type == TEEC_ION_SGLIST_INPUT);
+ if (teec_tmpmem_type(param_type, INOUT)) {
+ addr_a = addrs[index][0];
+ addr_b = addrs[index][1];
+
+ user_addr_a = (uintptr_t)(context->params[index].memref.size_addr
+ | (uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM);
+ user_addr_b = (uintptr_t)(context->params[index].memref.buffer
+ | (uint64_t)context->params[index].memref.buffer_h_addr << ADDR_TRANS_NUM);
+
+ if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) {
+ ret = -EFAULT;
+ }
+ if (copy_to_user((void *)user_addr_b, (void *)addr_b, *(uint32_t *)addr_a) != 0) {
+ ret = -EFAULT;
+ }
+ kfree((void *)addr_a);
+ kfree((void *)addr_b);
+
+ } else if(teec_memref_type(param_type, INOUT)) {
+ addr_a = addrs[index][0];
+
+ user_addr_a = (uintptr_t)(context->params[index].memref.size_addr
+ | (uint64_t)context->params[index].memref.size_h_addr << ADDR_TRANS_NUM);
+ if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) {
+ ret = -EFAULT;
+ }
+ kfree((void *)addr_a);
+ } else if(teec_value_type(param_type, INOUT) || checkValue) {
+ addr_a = addrs[index][0];
+ addr_b = addrs[index][1];
+ tlogd("val_a = %d\n", *(int *)addr_a);
+ tlogd("val_b = %d\n", *(int *)addr_b);
+ user_addr_a = (uintptr_t)(context->params[index].value.a_addr
+ | (uint64_t)context->params[index].value.a_h_addr << ADDR_TRANS_NUM);
+ user_addr_b = (uintptr_t)(context->params[index].value.b_addr
+ | (uint64_t)context->params[index].value.b_h_addr << ADDR_TRANS_NUM);
+
+ if (copy_to_user((void *)user_addr_a, (void *)addr_a, sizeof(uint32_t)) != 0) {
+ ret = -EFAULT;
+ }
+ if (copy_to_user((void *)user_addr_b, (void *)addr_b, sizeof(uint32_t)) != 0) {
+ ret = -EFAULT;
+ }
+ kfree((void *)addr_a);
+ //kfree(addr_b);
+ } else {
+ /* nothing */
+ }
+
+ if (ret) {
+ tloge(" ret =%d \n", ret);
+ }
+ }
+}
+
+int tc_ns_send_cmd(struct vtzf_dev_file *dev_file,
+ struct tc_ns_client_context *context)
+{
+ int ret = -EINVAL;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_send_cmd packet_cmd;
+ struct_packet_rsp_send_cmd packet_rsp;
+ uintptr_t addrs[4][3];
+ if (!dev_file || !context) {
+ tloge("invalid dev_file or context\n");
+ return ret;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_SEND_CMD;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ packet_cmd.cliContext = *context;
+ /* 重新给param分配空间 */
+
+ ret = alloc_for_params(dev_file, &packet_cmd, addrs);
+ if (ret) {
+ tloge("alloc for params failed \n");
+ return ret;
+ }
+
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ tlogd(" invoke cmd ret =%d \n", ret);
+ if (ret) {
+ tloge("invoke cmd failed ret is %d\n", ret);
+ }
+ /* 将数据拷贝回 */
+ /* 根据返回值写回*/
+ /*
+ if (tee_ret != 0) {
+ tloge("smc call ret 0x%x, cmd ret val 0x%x, origin %u\n", tee_ret,
+ op_params->smc_cmd->ret_val, op_params->smc_cmd->err_origin);
+
+ ret = EFAULT;
+ if (tee_ret == (int)TEEC_CLIENT_INTR)
+ ret = -ERESTARTSYS;
+
+ if (tee_ret == (int)TEEC_ERROR_SHORT_BUFFER)
+ (void)update_client_operation(call_params, op_params, false);
+ } else {
+ tz_log_write();
+ ret = update_client_operation(call_params, op_params, true);
+ }
+ */
+ free_for_params(&packet_cmd.cliContext, context, addrs);
+ context->returns = packet_cmd.cliContext.returns;
+
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+
+ return ret;
+}
+
+static int ioctl_session_send_cmd(struct vtzf_dev_file *dev_file,
+ struct tc_ns_client_context *context, void *argp)
+{
+ int ret;
+ ret = tc_ns_send_cmd(dev_file, context);
+ if (ret != 0)
+ tloge("send cmd failed ret is %d\n", ret);
+ if (copy_to_user(argp, context, sizeof(*context)) != 0) {
+ if (ret == 0)
+ ret = -EFAULT;
+ }
+ return ret;
+}
+
+int tc_client_session_ioctl(struct vtzf_dev_file *dev_file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -EINVAL;
+ void *argp = (void __user *)(uintptr_t)arg;
+ struct tc_ns_client_context context;
+
+
+ if (!argp || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+ if (copy_from_user(&context, argp, sizeof(context)) != 0) {
+ tloge("copy from user failed\n");
+ return -EFAULT;
+ }
+ //dump_buff((void *)(&context), sizeof(context));
+
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ:
+ ret = tc_ns_open_session(dev_file, &context);
+ tlogd("opensession session_id =%d\n", context.session_id);
+ if (copy_to_user(argp, &context, sizeof(context)) != 0 && ret == 0)
+ ret = -EFAULT;
+ break;
+
+ case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ:
+ ret = tc_ns_close_session(dev_file, argp);
+ break;
+
+ case TC_NS_CLIENT_IOCTL_SEND_CMD_REQ:
+ //tee_trace_add_event(INVOKE_CMD_START, 0);
+ tlogd(" CMD is TC_NS_CLIENT_IOCTL_SEND_CMD_REQ\n");
+ ret = ioctl_session_send_cmd(dev_file, &context, argp);
+ //tee_trace_add_event(INVOKE_CMD_END, 0);
+ break;
+
+ default:
+ tloge("invalid cmd:0x%x!\n", cmd);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int tc_ns_send_cancel_cmd(struct vtzf_dev_file *dev_file, void *argp)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_cancel_cmd packet_cmd;
+ struct_packet_rsp_cancel_cmd packet_rsp;
+ (void)dev_file;
+ if (!argp || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_CANCEL_CMD;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+
+ if (copy_from_user(&packet_cmd.cliContext, argp, sizeof(packet_cmd.cliContext)) != 0) {
+ tloge("copy from user failed\n");
+ return -ENOMEM;
+ }
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ if (copy_to_user(argp, &packet_rsp.cliContext, sizeof(packet_rsp.cliContext)) != 0)
+ ret = -EFAULT;
+ }
+
+END:
+ return ret;
+}
+
+static int tc_ns_client_login_func(struct vtzf_dev_file *dev_file,
+ const void __user *buffer)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_login_non packet_cmd_non;
+ struct_packet_cmd_login packet_cmd;
+ struct_packet_rsp_login packet_rsp;
+
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ /* 这里登录信息buffer有两种情况,一种为NULL */
+ if (!buffer) {
+ packet_cmd_non.seq_num = seq_num;
+ packet_cmd_non.cmd = VTZF_LOG_IN_NHIDL;
+ packet_cmd_non.ptzfd = dev_file->ptzfd;
+ if (send_to_proxy(&packet_cmd_non, sizeof(packet_cmd_non), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ }
+ ret = packet_rsp.ret;
+ goto END;
+ }
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_LOG_IN;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+
+ /* 发送地址,让TZdriver 去读会更快???*/
+ if (copy_from_user(&packet_cmd.cert_buffer, buffer, BUF_MAX_SIZE) != 0) {
+ tloge("copy from user failed\n");
+ ret = -EFAULT;
+ goto END;
+ }
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ }
+
+END:
+ return ret;
+}
+
+
+static int tc_ns_get_tee_version(struct vtzf_dev_file *dev_file, void __user *argp)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_getteever packet_cmd;
+ struct_packet_rsp_getteever packet_rsp;
+ tlogd("**********cmd is get ver **********\n");
+ packet_cmd.cmd = VTZF_GET_TEE_VERSION;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ /* There is no ptzfd, the TZdriver is opened and close immediately after use */
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ if (copy_to_user(argp, &packet_rsp.tee_ver, sizeof(uint32_t)) != 0)
+ ret = -EFAULT;
+ }
+
+END:
+ return ret;
+}
+
+int tc_ns_get_tee_info(struct vtzf_dev_file *dev_file, void __user *argp)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_getteeinfo packet_cmd;
+ struct_packet_rsp_getteeinfo packet_rsp;
+ tlogd("**********cmd is get info**********\n");
+ if (!argp || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.cmd = VTZF_GET_TEE_INFO;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ if (copy_to_user(argp, &packet_rsp.info, sizeof(struct tc_ns_tee_info)) != 0)
+ ret = -EFAULT;
+ }
+
+END:
+ return ret;
+}
+
+static int tc_ns_late_init(unsigned long arg)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_lateinit packet_cmd;
+ struct_packet_rsp_lateinit packet_rsp;
+
+ packet_cmd.cmd = VTZF_LATE_INIT;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.index = (uint32_t)arg;
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ }
+
+END:
+ return ret;
+}
+
+static int sync_system_time_from_user(struct vtzf_dev_file *dev_file,
+ const struct tc_ns_client_time *user_time)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_synctime packet_cmd;
+ struct_packet_rsp_synctime packet_rsp;
+ struct tc_ns_client_time time = { 0 };
+
+ if (!user_time) {
+ tloge("user time is NULL input buffer\n");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&packet_cmd.tcNsTime, user_time, sizeof(time))) {
+ tloge("copy from user failed\n");
+ return -EFAULT;
+ }
+ packet_cmd.cmd = VTZF_SYNC_TIME;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ /* There is no ptzfd, the TZdriver is opened and close immediately after use */
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ }
+END:
+ return ret;
+}
+
+static bool is_valid_agent(unsigned int buffer_size)
+{
+ if (buffer_size > SZ_4K) {
+ tloge("size: %u of user agent's shared mem is invalid\n", buffer_size);
+ return false;
+ }
+ return true;
+}
+
+static unsigned long agent_buffer_map(unsigned long phy_buffer, uint32_t size)
+{
+ struct vm_area_struct *vma = NULL;
+ unsigned long user_addr;
+ int ret;
+
+ user_addr = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, 0);
+ if (IS_ERR_VALUE((uintptr_t)user_addr)) {
+ tloge("vm mmap failed\n");
+ return user_addr;
+ }
+
+ down_read(&mm_sem_lock(current->mm));
+ vma = find_vma(current->mm, user_addr);
+ if (!vma) {
+ tloge("user_addr is not valid in vma");
+ goto err_out;
+ }
+
+ ret = remap_pfn_range(vma, user_addr, phy_buffer >> PAGE_SHIFT, size,
+ vma->vm_page_prot);
+ if (ret != 0) {
+ tloge("remap agent buffer failed, err=%d", ret);
+ goto err_out;
+ }
+
+ up_read(&mm_sem_lock(current->mm));
+ return user_addr;
+err_out:
+ up_read(&mm_sem_lock(current->mm));
+ if (vm_munmap(user_addr, size))
+ tloge("munmap failed\n");
+ return 0;
+}
+
+static int ioctl_register_agent(struct vtzf_dev_file *dev_file, void __user *argp)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_regagent packet_cmd;
+ struct_packet_rsp_regagent packet_rsp;
+ struct vtz_shared_mem *shared_mem = NULL;
+ size_t size;
+ void *buffer;
+ void *user_addr;
+ tlogd("********** cmd is reg_agent **********");
+
+ if (!argp || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&packet_cmd.args, (void *)(uintptr_t)argp, sizeof(packet_cmd.args)) != 0) {
+ tloge("copy agent args failed\n");
+ return -EFAULT;
+ }
+
+ /* 分配空间,维护对应关packet_cmd系*/
+ if (!is_valid_agent(packet_cmd.args.buffer_size)) {
+ return -EINVAL;
+ }
+ size = (size_t)packet_cmd.args.buffer_size;
+ size = ALIGN(size, SZ_4K);
+ shared_mem = kzalloc(sizeof(*shared_mem), GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)shared_mem)) {
+ tloge("shared_mem malloc failed\n");
+ return -ENOMEM;
+ }
+ buffer = kzalloc(size, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) {
+ tloge("buffer malloc failed\n");
+ kfree(shared_mem);
+ return -ENOMEM;
+ }
+ user_addr = (void*)agent_buffer_map(virt_to_phys(buffer), size);
+ if (!user_addr) {
+ kfree(shared_mem);
+ kfree(buffer);
+ return -ENOMEM;
+ }
+ shared_mem->kernel_addr = buffer;
+ shared_mem->user_addr = user_addr;
+ shared_mem->len = size;
+ *(int*)buffer = 985;
+
+ mutex_lock(&dev_file->shared_mem_lock);
+ list_add_tail(&shared_mem->head, &dev_file->shared_mem_list);
+ mutex_unlock(&dev_file->shared_mem_lock);
+
+ packet_cmd.cmd = VTZF_FS_REGISTER_AGENT;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ packet_cmd.phyaddr = virt_to_phys(buffer);
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ ret = -EFAULT;
+ goto END;
+ } else {
+ ret = packet_rsp.ret;
+ if (!ret) {
+ shared_mem->user_addr_host = packet_rsp.args.buffer;
+ packet_rsp.args.buffer = user_addr;
+ } else{
+ kfree(shared_mem);
+ kfree(buffer);
+ }
+ tlogd("packet_rsp.ret = %d \n", packet_rsp.ret);
+ if (copy_to_user(argp, &packet_rsp.args, sizeof(packet_rsp.args)) != 0) {
+ ret = -EFAULT;
+ }
+ }
+
+END:
+ return ret;
+}
+
+static int send_wait_event(struct vtzf_dev_file *dev_file, unsigned int agent_id)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_event packet_cmd;
+ struct_packet_rsp_general packet_rsp;
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.cmd = VTZF_WAIT_EVENT;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ packet_cmd.agent_id = agent_id;
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ tloge("sen to proxy failed\n");
+ return -EFAULT;
+ } else {
+ ret = packet_rsp.ret;
+ }
+ return ret;
+}
+
+static int send_event_response(struct vtzf_dev_file *dev_file, unsigned int agent_id)
+{
+ int ret = 0;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_event packet_cmd;
+ struct_packet_rsp_general packet_rsp;
+ if (!dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.cmd = VTZF_SEND_EVENT_RESPONSE;
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+ packet_cmd.agent_id = agent_id;
+
+ if (send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num)) {
+ tloge("sen to proxy failed\n");
+ return -EFAULT;
+ } else {
+ ret = packet_rsp.ret;
+ }
+ return ret;
+}
+
+static int tc_ns_load_secfile(struct vtzf_dev_file *dev_file,
+ struct load_secfile_ioctl_struct *ioctlArg)
+{
+ int ret;
+ uint32_t seq_num = get_seq_num();
+ struct_packet_cmd_load_sec packet_cmd;
+ struct_packet_rsp_load_sec packet_rsp;
+ size_t file_size;
+ char *buffer = NULL, *tmp_buffer = NULL;
+
+ if (!ioctlArg || !dev_file) {
+ tloge("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dev_file->ptzfd <= 0) {
+ tloge("The TZdriver on the host has not been opened yet\n");
+ return -EINVAL;
+ }
+
+ packet_cmd.seq_num = seq_num;
+ packet_cmd.cmd = VTZF_LOAD_SEC;
+ packet_cmd.ptzfd = dev_file->ptzfd;
+
+ packet_cmd.ioctlArg = *ioctlArg;
+ //if (copy_from_user(&(packet_cmd.ioctlArg), argp, sizeof(packet_cmd.ioctlArg) != 0)) {
+ // return -EFAULT;
+ //}
+ /* 有Buffer地址需要转换char *cliContext.file_buffer */
+ file_size = (size_t)packet_cmd.ioctlArg.sec_file_info.file_size;
+ tlogd("file_size = %lu \n", file_size);
+ buffer = (char *)kzalloc(file_size, GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) {
+ tloge("vtzf_dev_file malloc failed\n");
+ return -ENOMEM;
+ }
+ /* 保存原地址并返回给用户,libteec会释放这个地址 */
+ tmp_buffer = packet_cmd.ioctlArg.file_buffer;
+ //tlogd("sizeof(char *) = %lu, sizeof(void*) =%lu ,sizeof(unsigned long) =%lu\n", sizeof(char *), sizeof(void*), sizeof(unsigned long));
+ //tlogd("buffer addr = %016llx ,tmp_buffer =%016llx \n", (unsigned long long)ioctlArg->file_buffer, (unsigned long long)tmp_buffer);
+ packet_cmd.ioctlArg.file_buffer = virt_to_phys(buffer);
+
+
+ /* 将image数据从用户拷贝到内核 */
+
+ if (copy_from_user(buffer, (const void __user *)tmp_buffer, file_size)) {
+ tloge("file buf get failed \n");
+ ret = -EFAULT;
+ goto END;
+ }
+ tlogd("------------image\n");
+ dump_buff((void *)(buffer), 32);
+
+ ret = send_to_proxy(&packet_cmd, sizeof(packet_cmd), &packet_rsp, sizeof(packet_rsp), seq_num);
+ if (!ret) {
+ ret = packet_rsp.ret;
+ tlogd(" load_secfile ret =%d \n", ret);
+ if (ret) {
+ tloge("load_secfile failed ret is %d\n", ret);
+ }
+ /* 还原地址,并将返回的内容拷贝回 */
+ packet_rsp.ioctlArg.file_buffer = tmp_buffer;
+ //if (copy_to_user(argp, &packet_rsp.ioctlArg, sizeof(struct load_secfile_ioctl_struct)) != 0){
+ // ret = -EFAULT;
+ //}
+ *ioctlArg = packet_rsp.ioctlArg;
+ } else {
+ tloge("send to proxy failed ret is %d\n", ret);
+ }
+END:
+ kfree(buffer);
+ return ret;
+}
+
+int public_ioctl(const struct file *file, unsigned int cmd,
+ unsigned long arg, bool is_from_client_node)
+{
+ int ret = -EINVAL;
+ void *argp = (void __user *)(uintptr_t)arg;
+ struct vtzf_dev_file *dev_file = NULL;
+ struct load_secfile_ioctl_struct ioctlArg;
+ dev_file = file->private_data;
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_WAIT_EVENT:
+ ret = send_wait_event(dev_file, (unsigned int)arg);
+
+ break;
+ case TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE:
+ ret = send_event_response(dev_file, (unsigned int)arg);
+
+ break;
+ case TC_NS_CLIENT_IOCTL_REGISTER_AGENT:
+ ret = ioctl_register_agent(dev_file, (void *)arg);
+ tlogd("****ioctl_register_agent ret=%d****",ret);
+ break;
+ case TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT:
+ /*
+ if (ioctl_check_agent_owner(dev_file, (unsigned int)arg, nsid) != 0)
+ return -EINVAL;
+ ret = tc_ns_unregister_agent((unsigned int)arg, nsid);
+ */
+ break;
+ case TC_NS_CLIENT_IOCTL_LOAD_APP_REQ:
+ if (copy_from_user(&ioctlArg, argp, sizeof(ioctlArg)) != 0) {
+ tloge("copy from user failed\n");
+ return -EFAULT;
+ }
+ ret = tc_ns_load_secfile(file->private_data, &ioctlArg);
+ if (copy_to_user(argp, &ioctlArg, sizeof(ioctlArg)) != 0 && ret == 0)
+ ret = -EFAULT;
+ break;
+ default:
+ tloge("invalid cmd!");
+ return ret;
+ }
+ return ret;
+}
+
+static long tc_private_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
+ //handle_cmd_prepare(cmd);
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_GET_TEE_VERSION:
+ ret = tc_ns_get_tee_version(file->private_data, argp);
+ break;
+ case TC_NS_CLIENT_IOCTL_GET_TEE_INFO:
+ ret = tc_ns_get_tee_info(file->private_data, argp);
+ break;
+ //case TC_NS_CLIENT_IOCTL_SET_NATIVECA_IDENTITY:
+ // 涉及到一个大的Buffer
+ //mutex_lock(&g_set_ca_hash_lock);
+ //ret = tc_ns_set_native_hash((unsigned long)(uintptr_t)argp, GLOBAL_CMD_ID_SET_CA_HASH);
+ //mutex_unlock(&g_set_ca_hash_lock);
+ // break;
+ case TC_NS_CLIENT_IOCTL_LATEINIT:
+ ret = tc_ns_late_init(arg);
+ break;
+ case TC_NS_CLIENT_IOCTL_SYC_SYS_TIME:
+ ret = sync_system_time_from_user(file->private_data, (struct tc_ns_client_time *)(uintptr_t)arg);
+ break;
+ default:
+ // 安全存储相关
+ ret = public_ioctl(file, cmd, arg, false);
+ tlogd("***** public ret = %d ******", ret);
+ break;
+ }
+
+ //handle_cmd_finish(cmd);
+
+ return ret;
+}
+
+static long tc_cvm_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -EFAULT;
+ void *argp = (void __user *)(uintptr_t)arg;
+ //handle_cmd_prepare(cmd);
+
+ switch (cmd) {
+ case TC_NS_CLIENT_IOCTL_GET_TEE_INFO:
+ ret = tc_ns_get_tee_info(file->private_data, argp);
+ break;
+
+#ifdef CONFIG_TEE_TELEPORT_SUPPORT
+ case TC_NS_CLIENT_IOCTL_PORTAL_REGISTER:
+ if (check_tee_teleport_auth() == 0)
+ ret = tee_portal_register(file->private_data, argp);
+ else
+ tloge("check tee_teleport path failed\n");
+ break;
+ case TC_NS_CLIENT_IOCTL_PORTAL_WORK:
+ if (check_tee_teleport_auth() == 0)
+ ret = tee_portal_work(file->private_data);
+ else
+ tloge("check tee_teleport path failed\n");
+ break;
+#endif
+ default:
+ ret = public_ioctl(file, cmd, arg, false);
+ break;
+ }
+
+ //handle_cmd_finish(cmd);
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+long tc_compat_client_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret;
+
+ if (!file)
+ return -EINVAL;
+
+ ret = tc_client_ioctl(file, cmd, (unsigned long)(uintptr_t)compat_ptr(arg));
+ return ret;
+}
+
+long tc_compat_private_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret;
+
+ if (!file)
+ return -EINVAL;
+
+ ret = tc_private_ioctl(file, cmd, (unsigned long)(uintptr_t)compat_ptr(arg));
+ return ret;
+}
+
+long tc_compat_cvm_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret;
+
+ if (!file)
+ return -EINVAL;
+
+ ret = tc_cvm_ioctl(file, cmd, (unsigned long)(uintptr_t)compat_ptr(arg));
+ return ret;
+}
+
+#endif
+
+
+
+static int send_to_proxy(void * wrt_buf, size_t size_wrt_buf, void * rd_buf, size_t size_rd_buf, uint32_t seq_num)
+{
+ int ret = 0;
+ loff_t off_vtzf_serialport = 0;
+ ssize_t ssize_ret = 0;
+ struct vtzf_serial_port_file *file;
+ struct file *fp_serialport;
+
+ file = alloc_serial_port();
+ if (file == NULL) {
+ return -EFAULT;
+ }
+ fp_serialport = file->filep;
+ if (fp_serialport == NULL) {
+ ret = -EFAULT;
+ goto END;
+ }
+ if ( !(fp_serialport->f_mode & FMODE_CAN_READ) ) {
+ tloge("%s is not readable \n", VTZF_SERIALPORT);
+ ret = -EFAULT;
+ goto END;
+ }
+
+ ssize_ret = kernel_write( fp_serialport, wrt_buf, size_wrt_buf, &off_vtzf_serialport );
+ tlogd("after write vtzf_packet_cmd to %s, ret value = %d, offset = %ld \n",
+ VTZF_SERIALPORT, (int)ssize_ret, (long)off_vtzf_serialport);
+
+ while(1) {
+ off_vtzf_serialport = 0;
+ ssize_ret = kernel_read(fp_serialport, file->buffer, SERIAL_PORT_BUF_LEN, &off_vtzf_serialport);
+ tlogd("after read vtzf_packet_rsp from %s, ret value = %d, offset = %ld \n",
+ VTZF_SERIALPORT, (int)ssize_ret, (long)off_vtzf_serialport);
+ if (ssize_ret <= 0) {
+ tloge("Failed to read vtzf_packet_rsp from %s, ret value = %d \n", VTZF_SERIALPORT, (int)ssize_ret);
+ ret = ssize_ret;
+ goto END;
+ } else if(ssize_ret < 4 ){
+ continue;
+ } else{
+ if (*(int *)(file->buffer) == seq_num +1) {
+ tlogd("read vtzf_packet_rsp succeed, ssize_ret =%d, size_rd_buf =%d \n", (int)ssize_ret, (int)size_rd_buf);
+ if (memcpy_s(rd_buf, size_rd_buf, file->buffer, size_rd_buf) != 0) {
+ ret = -EFAULT;
+ goto END;
+ }
+ break;
+ }
+ /* old data, continue */
+ }
+ }
+
+ ret = 0;
+
+END:
+ free_serial_port(file, ssize_ret);
+ return ret;
+}
+
+
+
+MODULE_DESCRIPTION("virtual trustzone frontend driver");
+MODULE_VERSION("1.00");
+MODULE_AUTHOR("TrustCute");
+
+module_init(vtzf_init);
+module_exit(vtzf_exit);
+
+MODULE_LICENSE("GPL");
+
+
+
+
+
+
diff --git a/trustzone-awared-vm/vm/vtzdriver/vtzf.h b/trustzone-awared-vm/vm/vtzdriver/vtzf.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b9d5376405901dbbcbd8256d6da9f48b40cd57a
--- /dev/null
+++ b/trustzone-awared-vm/vm/vtzdriver/vtzf.h
@@ -0,0 +1,414 @@
+#ifndef VTZF_H
+#define VTZF_H
+
+#include
+#include
+//#include
+#include "tc_ns_client.h"
+#include "teek_ns_client.h"
+
+#define VTZF_DEV "vtzf"
+#define CONFIG_CONFIDENTIAL_CONTAINER
+#ifndef SECURITY_AUTH_ENHANCE
+#define SECURITY_AUTH_ENHANCE
+#endif
+
+#ifndef ZERO_SIZE_PTR
+#define ZERO_SIZE_PTR ((void *)16)
+#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR)
+#endif
+
+#define INVALID_MAP_ADDR ((void*)-1)
+#define MAILBOX_POOL_SIZE SZ_4M
+#define BUF_MAX_SIZE 2048
+#define SERIAL_PORT_BUF_LEN 1024
+#define VTZF_SERIALPORT "/dev/virtio-ports/vtzf_serialport"
+#define SERIAL_PORT_NUM 5
+
+#define TC_NS_CLIENT_DEV_FLAG 3
+#define TC_PRIVATE_DEV_FLAG 4
+#define TC_CVM_DEV_FLAG 5
+
+#define VTZF_OPEN_TZD 15
+#define VTZF_CLOSE_TZD 17
+#define VTZF_LOG_IN_NHIDL 19
+#define VTZF_GET_TEE_VERSION 21
+#define VTZF_GET_TEE_INFO 23
+#define VTZF_LATE_INIT 25
+#define VTZF_SYNC_TIME 27
+#define VTZF_LOG_IN 29
+#define VTZF_OPEN_SESSION 31
+#define VTZF_SEND_CMD 33
+#define VTZF_CANCEL_CMD 35
+#define VTZF_MMAP 37
+#define VTZF_MUNMAP 39
+#define VTZF_CLOSE_SESSION 41
+#define VTZF_CLOSE_PTZDEV 43
+#define VTZF_FS_REGISTER_AGENT 45
+#define VTZF_WAIT_EVENT 49
+#define VTZF_SEND_EVENT_RESPONSE 51
+#define VTZF_LOAD_SEC 53
+#define VTZF_TEST 47
+
+#define IS_TEMP_MEM(paramType) \
+ (((paramType) == TEEC_MEMREF_TEMP_INPUT) || ((paramType) == TEEC_MEMREF_TEMP_OUTPUT) || \
+ ((paramType) == TEEC_MEMREF_TEMP_INOUT))
+
+#define IS_PARTIAL_MEM(paramType) \
+ (((paramType) == TEEC_MEMREF_WHOLE) || ((paramType) == TEEC_MEMREF_PARTIAL_INPUT) || \
+ ((paramType) == TEEC_MEMREF_PARTIAL_OUTPUT) || ((paramType) == TEEC_MEMREF_PARTIAL_INOUT))
+
+#define IS_VALUE_MEM(paramType) \
+ (((paramType) == TEEC_VALUE_INPUT) || ((paramType) == TEEC_VALUE_OUTPUT) || ((paramType) == TEEC_VALUE_INOUT))
+
+/* Use during device initialization */
+struct dev_node {
+ struct class *driver_class;
+ struct cdev char_dev;
+ dev_t devt;
+ struct device *class_dev;
+ const struct file_operations *fops;
+ char *node_name;
+};
+
+/* List of devices that have already been opened*/
+struct vtzf_dev_list {
+ struct mutex dev_lock; /* for dev_file_list */
+ struct list_head dev_file_list;
+};
+
+struct vtzf_serial_port_list {
+ struct mutex lock; /* for dev_file_list */
+ struct list_head head;
+};
+
+struct vtzf_serial_port_file
+{
+ struct file *filep;
+ struct list_head head;
+ struct mutex lock;
+ bool using;
+ void *buffer;
+};
+
+struct vtz_shared_mem {
+ void *kernel_addr;
+ void *user_addr;
+ void *user_addr_host;
+ unsigned int len;
+ int mem_type;
+ struct list_head head;
+ atomic_t usage;
+ atomic_t offset;
+};
+
+struct vtzf_dev_file {
+ unsigned int dev_file_id;
+ int32_t ptzfd;
+ // struct mutex service_lock; /* for service_ref[], services[] */
+ // uint8_t service_ref[SERVICES_MAX_COUNT]; /* a judge if set services[i]=NULL */
+ // struct tc_ns_service *services[SERVICES_MAX_COUNT];
+ struct list_head head;
+ struct mutex shared_mem_lock; /* for shared_mem_list */
+ struct list_head shared_mem_list;
+ /* Device is linked to call from kernel */
+ // uint8_t kernel_api;
+ /* client login info provided by teecd, can be either package name and public
+ * key or uid(for non android services/daemons)
+ * login information can only be set once, dont' allow subsequent calls
+ */
+ // bool login_setup;
+ // struct mutex login_setup_lock; /* for login_setup */
+ // uint32_t pkg_name_len;
+ // uint8_t pkg_name[MAX_PACKAGE_NAME_LEN];
+ // uint32_t pub_key_len;
+ // uint8_t pub_key[MAX_PUBKEY_LEN];
+ // int load_app_flag;
+ // struct completion close_comp; /* for kthread close unclosed session */
+};
+
+struct vtzf_shared_mem {
+ void *kernel_virt_addr;
+ void *user_virt_addr;
+ void *phy_addr;
+ // void *user_addr_ca; /* for ca alloc share mem */
+ unsigned int len;
+ struct list_head head;
+ // atomic_t usage;
+ atomic_t offset;
+};
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_general;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num; // second
+} struct_packet_cmd_test;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_test;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num; // second
+ uint32_t vmid;
+ uint32_t flag;
+} struct_packet_cmd_open_tzd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ __s32 ptzfd;
+} struct_packet_rsp_open_tzd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num; // second
+ __s32 ptzfd;
+} struct_packet_cmd_close_tzd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_close_tzd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+} struct_packet_cmd_getteever;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ uint32_t tee_ver; // 4, 12 bytes
+} struct_packet_rsp_getteever;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+} struct_packet_cmd_getteeinfo;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ struct tc_ns_tee_info info;
+} struct_packet_rsp_getteeinfo;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ __s32 ptzfd;
+ void *phyaddr;
+ struct agent_ioctl_args args;
+} struct_packet_cmd_regagent;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ struct agent_ioctl_args args;
+} struct_packet_rsp_regagent;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ __s32 ptzfd;
+ uint32_t agent_id;
+} struct_packet_cmd_event;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ uint32_t index;
+} struct_packet_cmd_lateinit;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_lateinit;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+ struct tc_ns_client_time tcNsTime;
+} struct_packet_cmd_synctime;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_packet_rsp_synctime;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+ uint8_t cert_buffer[BUF_MAX_SIZE];
+} struct_packet_cmd_login;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+} struct_packet_cmd_login_non;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_login;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ __s32 ptzfd;
+ __s32 cpu_index;
+ struct load_secfile_ioctl_struct ioctlArg;
+} struct_packet_cmd_load_sec;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ struct load_secfile_ioctl_struct ioctlArg;
+} struct_packet_rsp_load_sec;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ __s32 ptzfd;
+ __s32 cpu_index;
+ struct tc_ns_client_context cliContext;
+} struct_packet_cmd_session;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+ struct tc_ns_client_context cliContext;
+} struct_packet_rsp_session;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd; // 4, 8 bytes
+ __s32 cpu_index; // 4, 12 bytes
+ unsigned long long addrs[TEE_PARAM_NUM];
+ struct tc_ns_client_context cliContext;
+} struct_packet_cmd_send_cmd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ struct tc_ns_client_context cliContext;
+} struct_packet_rsp_send_cmd;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd; // 4, 8 bytes
+ __s32 cpu_index; // 4, 12 bytes
+ struct tc_ns_client_context cliContext;
+ pid_t pid;
+} struct_packet_cmd_cancel_cmd;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ struct tc_ns_client_context cliContext;
+} struct_packet_rsp_cancel_cmd;
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t seq_num;
+ __s32 ptzfd;
+ uint64_t buffer;
+ uint32_t size;
+ uint32_t offset;
+} struct_packet_cmd_mmap;
+
+typedef struct {
+ uint32_t seq_num;
+ uint32_t ret;
+} struct_packet_rsp_mmap;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ __s32 ptzfd;
+} struct_vtzf_packet_cmd_closeptz;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+} struct_vtzf_packet_rsp_closeptz;
+
+typedef struct {
+ uint32_t cmd; // 4, 4 bytes
+ uint32_t seq_num;
+ void* buffer;
+ struct agent_ioctl_args args;
+} struct_vtzf_packet_cmd_fs_reg;
+
+typedef struct {
+ uint32_t seq_num; // 4, 4 bytes
+ uint32_t ret; // 4, 8 bytes
+ __s32 ptzfd; // 4, 12 bytes
+ struct agent_ioctl_args args;
+} struct_vtzf_packet_rsp_fs_reg;
+
+int tc_ns_client_open(struct vtzf_dev_file **dev_file, uint32_t flag);
+static int vtzf_client_open(struct inode *inode, struct file *file);
+static int vtzf_private_open(struct inode *inode, struct file *file);
+static int vtzf_cvm_open(struct inode *inode, struct file *file);
+int vtzf_close(struct inode *inode, struct file *file);
+void shared_vma_open(struct vm_area_struct *vma);
+void shared_vma_close(struct vm_area_struct *vma);
+static int vtzf_mmap(struct file *filp, struct vm_area_struct *vma);
+static long tc_client_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+static long tc_private_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+static long tc_cvm_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
+static int public_ioctl(const struct file *file, unsigned int cmd,
+ unsigned long arg, bool is_from_client_node);
+static int open_tzdriver(struct vtzf_dev_file *dev_file, uint32_t flag);
+static int close_tzdriver(struct vtzf_dev_file *dev_file);
+#ifdef CONFIG_COMPAT
+long tc_compat_client_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+long tc_compat_private_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+long tc_compat_cvm_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
+#endif
+
+static int proxy_mmap(struct vtzf_dev_file *dev_file, void * user_buffer,
+ uint32_t buffer_size, uint32_t pgoff, uint8_t unmap);
+static int send_to_proxy(void * wrt_buf, size_t size_wrt_buf,
+ void * rd_buf, size_t size_rd_buf, uint32_t seq_num);
+static struct vtzf_serial_port_file *alloc_serial_port(void);
+static void free_serial_port(struct vtzf_serial_port_file *file,
+ ssize_t ssize_ret);
+static uint32_t get_seq_num(void);
+int tc_ns_open_session(struct vtzf_dev_file *dev_file,
+ struct tc_ns_client_context *clicontext);
+int tc_client_session_ioctl(struct vtzf_dev_file *dev_file,
+ unsigned int cmd, unsigned long arg);
+static int tc_ns_send_cancel_cmd(struct vtzf_dev_file *dev_file, void *argp);
+
+static int tc_ns_client_login_func(struct vtzf_dev_file *dev_file,
+ const void __user *buffer);
+static int tc_ns_get_tee_version(struct vtzf_dev_file *dev_file,
+ void __user *argp);
+int tc_ns_get_tee_info(struct vtzf_dev_file *dev_file,
+ void __user *argp);
+static int tc_ns_late_init(unsigned long arg);
+static int sync_system_time_from_user(struct vtzf_dev_file *dev_file,
+ const struct tc_ns_client_time *user_time);
+#endif // VTZF_H
+
+
+