diff --git "a/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md" "b/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md"
new file mode 100644
index 0000000000000000000000000000000000000000..a7171d4e268621b189a8a55ba6ea22bc3d5e6240
--- /dev/null
+++ "b/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md"
@@ -0,0 +1,517 @@
+# 使用switchless特性
+
+## switchless特性介绍
+**技术定义:** switchless是一种通过共享内存减少REE与TEE上下文切换及数据拷贝次数,优化REE与TEE交互性能的技术。
+
+ **典型应用场景:** 传统应用做机密计算改造拆分成非安全侧CA与安全侧TA后
+
+- 当CA业务逻辑中存在频繁调用TA接口时,调用中间过程耗时占比较大,严重影响业务性能。
+- 当CA与TA存在频繁大块数据交换时,普通ECALL调用底层会有多次内存拷贝,导致性能低下。
+ 针对以上两种典型场景,可以通过switchless优化交互性能,降低机密计算拆分带来的性能损耗,最佳效果可达到与拆分前同等数量级。
+
+ **支持硬件平台:**
+
+- Intel SGX
+- ARM TrustZone 鲲鹏920
+
+## 约束限制
+虽然开启switchless节省了一定时间,但它们需要额外的线程来为调用提供服务。如果工作线程忙于等待消息,将会消耗大量CPU,另外更多的工作线程通常意味着更多的CPU资源竞争和更多的线程上下文切换,反而可能损害性能,所以switchless的最佳配置是经过实际业务模型与性能测试,在资源占用与性能要求中选出平衡点。
+
+##特性配置项规格
+用户调用cc_enclave_create创建Enclave时,需在feature参数中传入switchless的特性配置,配置项如下:
+```
+typedef struct {
+ uint32_t num_uworkers;
+ uint32_t num_tworkers;
+ uint32_t switchless_calls_pool_size;
+ uint32_t retries_before_fallback;
+ uint32_t retries_before_sleep;
+ uint32_t parameter_num;
+ uint32_t workers_policy;
+ uint32_t rollback_to_common;
+} cc_sl_config_t;
+```
+各配置项规格如下表:
+
+| 配置项 | 说明 |
+| ------------ | ---- |
+| num_uworkers | 非安全侧代理工作线程数,用于执行switchless OCALL,当前该字段仅在SGX平台生效,ARM平台可以配置,但是因ARM平台暂不支持OCALL,所以配置后不会生效。
规格:
ARM:最大值:512;最小值:1;默认值:8(当num_uworkers配置为0时,会使用默认参数)
SGX:最大值:4294967295;最小值:1|
+| num_tworkers | 安全侧代理工作线程数,用于执行switchless ECALL。
规格:
ARM:最大值:512;最小值:1;默认值:8(当num_tworkers配置为0时,会使用默认参数)
SGX:最大值:4294967295;最小值:1|
+| switchless_calls_pool_size | switchless调用任务池的大小,实际可容纳switchless_calls_pool_size * 64个switchless调用任务(例:switchless_calls_pool_size=1,可容纳64个switchless调用任务)。
规格:
ARM:最大值:8;最小值:1;默认值:1(配置为0时)
SGX:最大值:8;最小值:1;默认值:1(当switchless_calls_pool_size配置为0时,会使用默认参数)|
+| retries_before_fallback | 执行retries_before_fallback次汇编pause指令后,若switchless调用仍没有被另一侧的代理工作线程执行,就回退到switch调用模式,该字段仅在SGX平台生效。
规格:
SGX:最大值:4294967295;最小值:1;默认值:20000(当retries_before_fallback配置为0时,会使用默认参数)|
+| retries_before_sleep | 执行retries_before_sleep次汇编pause指令后,若代理工作线程一直没有等到有任务来,则进入休眠状态,该字段仅在SGX平台生效。
规格:
SGX:最大值:4294967295;最小值:1;默认值:20000(当retries_before_sleep配置为0时,会使用默认参数)|
+| parameter_num | switchless函数支持的最大参数个数,该字段仅在ARM平台生效,SGX平台无此限制。
规格:
ARM:最大值:16;最小值:0|
+| parameter_num | switchless函数支持的最大参数个数,该字段仅在ARM平台生效。
规格:
ARM:最大值:16;最小值:0|
+| workers_policy | switchless代理线程运行模式,该字段仅在ARM平台生效。
规格:
ARM:
WORKERS_POLICY_BUSY:代理线程一直占用CPU资源,无论是否有任务需要处理,适用于对性能要求极高且系统软硬件资源丰富的场景;
WORKERS_POLICY_WAKEUP:代理线程仅在有任务时被唤醒,处理完任务后进入休眠,等待再次被新任务唤醒|
+| rollback_to_common | 异步switchless调用失败时是否回退到普通调用,该字段仅在ARM平台生效。
规格:
ARM:0:否,失败时仅返回相应错误码;其他:是,失败时回退到普通调用|
+
+## switchless开发流程
+
+这里给出使用 switchless 特性开发一个 C 语言程序 switchless 的例子,方便用户理解使用 switchless 开发应用程序。
+
+基于secGear API开发应用的具体流程请参考[开发secGear应用程序.md](./开发secGear应用程序.md)
+
+1. 编写 EDL(Enclave Definition Language)文件
+
+ switchless 函数需添加'transition_using_threads'标识。
+
+ ```c
+ enclave {
+ include "secgear_urts.h"
+ from "secgear_tstdc.edl" import *;
+ from "secgear_tswitchless.edl" import *;
+ trusted {
+ public int get_string_switchless([out, size=32]char *buf) transition_using_threads;
+ };
+ };
+ ```
+
+2. 编写顶层文件 CMakeLists.txt
+
+ 编写顶层文件 CMakeLists.txt,置于 switchless 工作目录下,用于配置编译时的处理器架构、所需的 EDL 文件等信息。
+
+ 其中,EDL_FILE 是 EDL 文件,需用户指定,例子中为 switchless.edl。DPATH 是安全侧加载动态库,配置如例子中所示。
+
+ ```c
+ cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
+
+ project(switchless C)
+
+ set(CMAKE_C_STANDARD 99)
+
+ if (NOT DEFINED ENCLAVE)
+ set(ENCLAVE "SGX")
+ endif()
+ set(SGX_SDK_DEFAULT_PATH /opt/intel/sgxsdk)
+ set(GP_SDK_DEFAULT_PATH /opt/itrustee_sdk)
+ set(PL_SDK_DEFAULT_PATH /root/dev/sdk)
+
+ set(SGX_SSL_DEFAULT_PATH /opt/intel/sgxssl)
+ set(GP_SSL_DEFAULT_PATH /opt/itrustee_sdk/itrustee_sdk_ssl)
+
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+
+ if(${ENCLAVE} STREQUAL "GP")
+ if (NOT DEFINED SDK_PATH)
+ set(iTrusteeSDK ${GP_SDK_DEFAULT_PATH})
+ else()
+ set(iTrusteeSDK ${SDK_PATH})
+ endif()
+ message("Current Platform: ARM Trustzone, iTrustee SDK PATH:${iTrusteeSDK}")
+ if(NOT IS_DIRECTORY ${iTrusteeSDK})
+ message(FATAL_ERROR "Please provide the correct iTrusteeSDK path")
+ endif()
+ set(CC_GP ON)
+ endif()
+
+ if(${ENCLAVE} STREQUAL "SGX")
+ if (NOT DEFINED SDK_PATH)
+ set(SGXSDK ${SGX_SDK_DEFAULT_PATH})
+ else()
+ set(SGXSDK ${SDK_PATH})
+ endif()
+ message("Current Platform: Intel SGX, SGX SDK PATH:${SGXSDK}")
+ if(NOT IS_DIRECTORY ${SGXSDK})
+ message(FATAL_ERROR "Please provide the correct SGXSDK path")
+ endif()
+ set(CC_SGX ON)
+ endif()
+
+ if(${ENCLAVE} STREQUAL "PL")
+ if (NOT DEFINED SDK_PATH)
+ set(PLSDK ${PL_SDK_DEFAULT_PATH})
+ else()
+ set(PLSDK ${SDK_PATH})
+ endif()
+ message("Current Platform: RISC-V, Penglai SDK PATH:${PLSDK}")
+ if(NOT IS_DIRECTORY ${PLSDK})
+ message(FATAL_ERROR "Please provide the correct Penglai SDK path")
+ endif()
+ set(CC_PL ON)
+ endif()
+
+ set(CURRENT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+ #set edl name
+ set(EDL_FILE switchless.edl)
+ set(CODEGEN codegen)
+
+ if(CC_GP)
+ set(CODETYPE trustzone)
+ set(UUID ebc87fc2-05dc-41b3-85b9-f9f0ef481bad)
+ add_definitions(-DPATH="${LOCAL_ROOT_PATH_INSTALL}/data/${UUID}.sec")
+ endif()
+
+ if(CC_SGX)
+ set(CODETYPE sgx)
+ add_definitions(-DPATH="${CMAKE_CURRENT_BINARY_DIR}/enclave/enclave.signed.so")
+ endif()
+
+ add_subdirectory(${CURRENT_ROOT_PATH}/enclave)
+ add_subdirectory(${CURRENT_ROOT_PATH}/host)
+
+ ```
+
+3. 编写非安全侧代码和 CMakeLists.txt
+
+ 3.1 编写 main.c
+
+ 使用 cc_enclave_create 创建安全区 enclave 上下文时,需在 features 参数中传入 switchless 特性配置。使能 switchless 特性的主要工作有:创建任务池,大小由配置中的 switchless_call_pool_size 决定;根据 num_uworkers / num_tworkers 创建 Untrust / Trust 工作线程池等。
+
+ ```c
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include "enclave.h"
+ #include "secgear_uswitchless.h"
+ #include "secgear_shared_memory.h"
+ #include "switchless_u.h"
+
+ #define BUF_LEN 32
+
+ int main()
+ {
+ int retval = 0;
+ char *path = PATH;
+ char buf[BUF_LEN];
+ cc_enclave_t *context = NULL;
+ context = (cc_enclave_t *)malloc(sizeof(cc_enclave_t));
+ cc_enclave_result_t res = CC_FAIL;
+ char real_p[PATH_MAX];
+
+ /* switchless configuration */
+ cc_sl_config_t sl_cfg = CC_USWITCHLESS_CONFIG_INITIALIZER;
+ sl_cfg.num_tworkers = 2; /* 2 tworkers */
+ sl_cfg.sl_call_pool_size_qwords = 2; /* 2 * 64 tasks */
+ enclave_features_t features = {ENCLAVE_FEATURE_SWITCHLESS, (void *)&sl_cfg};
+
+ res = cc_enclave_create(real_p, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, &features, 1, context);
+ ...
+
+ char *shared_buf = (char *)cc_malloc_shared_memory(context, BUF_LEN);
+ ...
+
+ /* switchless ecall */
+ res = get_string_switchless(context, &retval, shared_buf);
+ if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) {
+ printf("Switchless ecall error\n");
+ } else {
+ printf("shared_buf: %s\n", shared_buf);
+ }
+
+ res = cc_free_shared_memory(context, shared_buf);
+ ...
+
+ res = cc_enclave_destroy(context);
+ ...
+
+ return res;
+ }
+ ```
+ [异步switchless调用](https://gitee.com/openeuler/secGear/blob/master/examples/switchless_performance/host/main.c),在调用ecall函数处变化有如下2点:
+ - 发起异步调用
+ ```c
+ /* async switchless ecall */
+ res = get_string_switchless_async(context, &task_id, &retval, shared_buf);
+ ...
+ ```
+ - 查询异步调用结果
+ ```c
+ /* 根据上一步返回的task_id, 查询异步调用结果 */
+ ret = cc_sl_get_async_result(context, task_id, &retval);
+ ...
+ ```
+
+ 3.2 编写非安全侧 CMakeLists.txt
+
+ ```c
+ # 设置编译环境变量
+ #set auto code prefix
+ set(PREFIX switchless)
+ #set host exec name
+ set(OUTPUT secgear_switchless)
+ #set host src code
+ set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/main.c)
+
+ # 使用代码生成工具生成辅助代码。CODEGEN 和 CODETYPE 变量也在顶层 CMakeLists.txt 中定义。--search-path 用于指定 switchless.edl 中导入依赖的其他 EDL 文件路径
+ # set auto code
+ if(CC_GP)
+ set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h
+ ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c
+ ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h)
+ add_custom_command(OUTPUT ${AUTO_FILES}
+ DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ COMMAND ${CODEGEN} --${CODETYPE}
+ --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ --search-path /usr/include/secGear)
+ endif()
+
+ if(CC_SGX)
+ set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c)
+ add_custom_command(OUTPUT ${AUTO_FILES}
+ DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ COMMAND ${CODEGEN} --${CODETYPE}
+ --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ --search-path /usr/include/secGear
+ --search-path ${SGXSDK}/include)
+ endif()
+
+ # 设置编译选项和链接选项
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -L/usr/lib64")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s")
+
+ # 编译链接引用目录
+ if(CC_GP)
+ if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
+ link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+ endif()
+ add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES})
+ target_include_directories(${OUTPUT} PRIVATE ${CMAKE_BINARY_DIR}/host
+ /usr/include/secGear
+ ${CMAKE_CURRENT_BINARY_DIR})
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
+ target_link_directories(${OUTPUT} PRIVATE /usr/lib64 ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+ endif()
+ endif()
+
+ if(CC_SGX)
+ if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
+ link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+ endif()
+ add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES})
+ target_include_directories(${OUTPUT} PRIVATE /usr/include/secGear
+ /opt/intel/sgxsdk/include
+ ${CMAKE_CURRENT_BINARY_DIR})
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
+ target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SGXSDK}/lib64)
+ endif()
+ endif()
+
+ if(CC_SIM)
+ target_link_libraries(${OUTPUT} secgearsim pthread)
+ else()
+ if(CC_GP)
+ target_link_libraries(${OUTPUT} secgear pthread)
+ endif()
+ if(CC_SGX)
+ target_link_libraries(${OUTPUT} secgear pthread -Wl,--whole-archive -lsgx_uswitchless -Wl,--no-whole-archive -lsgx_urts)
+ endif()
+ endif()
+
+ # 指定二进制安装目录
+ set_target_properties(${OUTPUT} PROPERTIES SKIP_BUILD_RPATH TRUE)
+ if(CC_GP)
+ install(TARGETS ${OUTPUT}
+ RUNTIME
+ DESTINATION ${LOCAL_ROOT_PATH_INSTALL}/vendor/bin/
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)
+ endif()
+
+ if(CC_SGX)
+ install(TARGETS ${OUTPUT}
+ RUNTIME
+ DESTINATION ${CMAKE_BINARY_DIR}/bin/
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)
+ endif()
+
+ ```
+
+4. 编写安全侧代码、CMakeLists.txt 和配置文件,放在 enclave 目录
+
+ 4.1 编写安全侧代码 enclave.c
+
+ ```c
+ #include
+ #include
+ #include "switchless_t.h"
+
+ #define TA_HELLO_WORLD "secgear hello world!"
+ #define BUF_MAX 32
+
+ int get_string_switchless(char *shared_buf)
+ {
+ strncpy(shared_buf, TA_HELLO_WORLD, strlen(TA_HELLO_WORLD) + 1);
+ return 0;
+ }
+
+ ```
+
+ 4.2 编写安全侧 CMakeLists.txt
+
+ ```
+ #set auto code prefix
+ set(PREFIX switchless)
+
+ #set sign key
+ set(PEM Enclave_private.pem)
+
+ #set sign tool
+ set(SIGN_TOOL sign_tool.sh)
+
+ #set enclave src code
+ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/enclave.c)
+
+ #set log level
+ set(PRINT_LEVEL 3)
+ add_definitions(-DPRINT_LEVEL=${PRINT_LEVEL})
+
+ # WHITE_LIST_x:为设置iTrustee的二进制白名单,用来设置哪些非安全侧的二进制可以调用安全侧的动态库。
+ # WHITE_LIST_OWNER:设置运行二进制所属的用户权限,只有该用户才可以调用安全侧动态库。
+ if(CC_GP)
+ #set signed output
+ set(OUTPUT ${UUID}.sec)
+ set(WHITE_LIST_0 ${LOCAL_ROOT_PATH_INSTALL}/vendor/bin/secgear_switchless)
+ set(WHITE_LIST_OWNER root)
+ set(WHITELIST WHITE_LIST_0)
+
+ set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h
+ ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c
+ ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h)
+
+ add_custom_command(OUTPUT ${AUTO_FILES}
+ DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ COMMAND ${CODEGEN} --${CODETYPE}
+ --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ --search-path /usr/include/secGear)
+ endif()
+
+ # SGX 安全侧动态库签名
+ if(CC_SGX)
+ set(OUTPUT enclave.signed.so)
+ set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c)
+ add_custom_command(OUTPUT ${AUTO_FILES}
+ DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ COMMAND ${CODEGEN} --${CODETYPE}
+ --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE}
+ --search-path /usr/include/secGear
+ --search-path ${SGXSDK}/include)
+ endif()
+
+ # 设置编译选项
+ set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer -fstack-protector-strong \
+ -Wstack-protector --param ssp-buffer-size=4 -frecord-gcc-switches -Wextra -nostdinc -nodefaultlibs \
+ -fno-peephole -fno-peephole2 -Wno-main -Wno-error=unused-parameter -D_FORTIFY_SOURCE=2 -O2 \
+ -Wno-error=unused-but-set-variable -L/usr/lib64 -Wno-error=format-truncation=")
+ set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles")
+
+ # itrustee 需生成 manifest.txt。指定 itrustee 编译选项和头文件、链接文件的搜索路径
+ if(CC_GP)
+ set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s -fPIC")
+ set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-s")
+
+ set(ITRUSTEE_TEEDIR ${iTrusteeSDK}/)
+ set(ITRUSTEE_LIBC ${iTrusteeSDK}/thirdparty/open_source/musl/libc)
+
+ if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
+ link_directories(${CMAKE_BINARY_DIR}/lib/)
+ endif()
+
+ add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES})
+
+ target_include_directories( ${PREFIX} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/enclave
+ /usr/include/secGear
+ ${ITRUSTEE_TEEDIR}/include/TA
+ ${ITRUSTEE_TEEDIR}/include/TA/huawei_ext
+ ${ITRUSTEE_LIBC}/arch/aarch64
+ ${ITRUSTEE_LIBC}/
+ ${ITRUSTEE_LIBC}/arch/arm/bits
+ ${ITRUSTEE_LIBC}/arch/generic
+ ${ITRUSTEE_LIBC}/arch/arm)
+
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
+ target_link_directories(${PREFIX} PUBLIC /usr/lib64)
+ endif()
+
+ foreach(WHITE_LIST ${WHITELIST})
+ add_definitions(-D${WHITE_LIST}="${${WHITE_LIST}}")
+ endforeach(WHITE_LIST)
+ add_definitions(-DWHITE_LIST_OWNER="${WHITE_LIST_OWNER}")
+
+ target_link_libraries(${PREFIX} secgear_tee)
+
+ #for trustzone compiling, you should connact us to get config and private_key.pem for test, so we will not sign and install binary in this example #
+ add_custom_command(TARGET ${PREFIX}
+ POST_BUILD
+ COMMAND bash ${SIGN_TOOL} -d sign
+ -x trustzone
+ -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so
+ -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt
+ -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini
+ -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT})
+
+ install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}
+ #DESTINATION /data
+ DESTINATION ${LOCAL_ROOT_PATH_INSTALL}/data
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+ endif()
+
+ if(CC_SGX)
+ set(SGX_DIR ${SGXSDK})
+ set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -m64 -fvisibility=hidden")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s")
+ set(LINK_LIBRARY_PATH ${SGX_DIR}/lib64)
+
+ if(CC_SIM)
+ set(Trts_Library_Name sgx_trts_sim)
+ set(Service_Library_Name sgx_tservice_sim)
+ else()
+ set(Trts_Library_Name sgx_trts)
+ set(Service_Library_Name sgx_tservice)
+ endif()
+
+ set(Crypto_Library_Name sgx_tcrypto)
+
+ set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-z,defs -Wl,-pie -Bstatic -Bsymbolic -eenclave_entry \
+ -Wl,--export-dynamic -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \
+ -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/Enclave.lds")
+
+ if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
+ link_directories(${LINK_LIBRARY_PATH})
+ endif()
+
+ add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES})
+
+ target_include_directories(${PREFIX} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ /usr/include/secGear
+ ${SGX_DIR}/include/tlibc
+ ${SGX_DIR}/include/libcxx
+ ${SGX_DIR}/include)
+
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
+ target_link_directories(${PREFIX} PRIVATE ${LINK_LIBRARY_PATH})
+ endif()
+
+ target_link_libraries(${PREFIX} -Wl,--whole-archive -lsgx_tswitchless ${Trts_Library_Name} -Wl,--no-whole-archive -Wl,--start-group
+ -lsgx_tstdc -lsgx_tcxx -l${Crypto_Library_Name} -l${Service_Library_Name} -Wl,--end-group)
+ add_custom_command(TARGET ${PREFIX}
+ POST_BUILD
+ COMMAND umask 0177
+ COMMAND openssl genrsa -3 -out ${PEM} 3072
+ COMMAND bash ${SIGN_TOOL} -d sign
+ -x sgx
+ -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so
+ -k ${PEM}
+ -o ${OUTPUT}
+ -c ${CMAKE_CURRENT_SOURCE_DIR}/Enclave.config.xml)
+ endif()
+
+ if(NOT DEFINED CC_PL)
+ set_target_properties(${PREFIX} PROPERTIES SKIP_BUILD_RPATH TRUE)
+ endif()
+ ```
+
+## 常见问题
+- sgx环境下开启switchless特性创建enclave后,直接销毁enclave,再使用enclave会产生core dump
+
+ sgx开启switchless需有以下两步:
+
+ 1. cc_enclave_create时传入switchless feature参数
+ 2. 在第一次ecall调用中初始化switchless线程调度
+
+ 如果没有调用ecall函数,就直接调用cc_enclave_destroy,会在sgx库中销毁switchless调度线程时异常。
+
+ 由于switchless的实际应用场景是存在频繁ecall调用的,所以初始化switchless特性后,通常会有ecall调用,不会存在问题。
\ No newline at end of file
diff --git "a/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md" "b/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md"
index a08550716dcaf85b04c3c51f9bf8fd261497fd84..e425f41021f16a62c840de70e92a6aa1d2b80284 100644
--- "a/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md"
+++ "b/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md"
@@ -67,6 +67,56 @@ cc_enclave_result_t cc_enclave_destroy (cc_enclave_t ** enclave);
- CC_ERROR_UNEXPECTED:不可预期错误
+## cc_malloc_shared_memory
+
+创建共享内存
+
+**功能**:
+
+开启switchless特性后,创建安全环境与非安全环境可同时访问的共享内存,由非安全侧调用
+
+**函数声明:**
+
+void *cc_malloc_shared_memory(cc_enclave_t *enclave, size_t size);
+
+**参数:**
+
+- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用,SGX平台该入参会被忽略
+- size:入参,共享内存大小
+
+**返回值:**
+
+- NULL:共享内存申请失败
+- 其他:为创建的共享内存的首地址
+
+
+## cc_free_shared_memory
+
+释放共享内存
+
+**功能**:
+
+开启switchless特性后,释放共享内存,由非安全侧调用
+
+**函数声明:**
+
+cc_enclave_result_t cc_free_shared_memory(cc_enclave_t *enclave, void *ptr);
+
+**参数:**
+
+- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用(该参数必须与调用cc_malloc_shared_memory接口时传入的enclave保持一致),SGX平台该入参会被忽略
+- ptr:入参,cc_malloc_shared_memory接口返回的共享内存地址
+
+**返回值:**
+
+- CC_ERROR_BAD_PARAMETERS:入参非法
+- CC_ERROR_INVALID_HANDLE:无效enclave或者传入的enclave与ptr所对应的enclave不匹配(仅在ARM平台生效,SGX平台会忽略enclave,故不会对enclave进行检查)
+- CC_ERROR_NOT_IMPLEMENTED:该接口未实现
+- CC_ERROR_SHARED_MEMORY_START_ADDR_INVALID:ptr不是cc_malloc_shared_memory接口返回的共享内存地址(仅在ARM平台生效)
+- CC_ERROR_OUT_OF_MEMORY:内存不足(仅在ARM平台生效)
+- CC_FAIL:一般性错误
+- CC_SUCCESS:成功
+
## cc_enclave_generate_random
@@ -291,3 +341,28 @@ void PrintInfo(int level, const char *fmt, ...);
**返回值:**
- 无
+
+## cc_sl_get_async_result
+
+获取异步switchless调用结果(仅支持ARM)
+
+**功能**:
+
+用于获取异步switchless调用执行结果,若异步switchless调用仍在处理中,该函数可多次调用直至获取最终结果,由非安全侧调用
+
+**函数声明:**
+
+cc_enclave_result_t cc_sl_get_async_result(cc_enclave_t *enclave, int task_id, void *retval)
+
+**参数:**
+
+- enclave:入参,已经创建 enclave 的上下文
+- task_id:入参,异步switchless调用的任务编号
+- retval:出参,用于接收异步switchless调用的返回值
+
+**返回值:**
+
+- CE_SUCCESS:调用成功
+- CC_ERROR_TASK_UNFINISH:异步switchless调用处理中
+- CC_ERROR_TASK_FAILED:异步调用框架执行失败
+- 其他:一般性错误
diff --git a/docs/zh/menu/index.md b/docs/zh/menu/index.md
index 3d7f6b188bb39e0f12d537b58a9a88c3834a9c4d..1822590c06e55428e6cd61f370632738aa6aeb91 100644
--- a/docs/zh/menu/index.md
+++ b/docs/zh/menu/index.md
@@ -161,6 +161,7 @@ headless: true
- [认识secGear]({{< relref "./docs/secGear/认识secGear.md" >}})
- [安装secGear]({{< relref "./docs/secGear/安装secGear.md" >}})
- [开发secGear应用程序]({{< relref "./docs/secGear/开发secGear应用程序.md" >}})
+ - [使用switchless特性]({{< relref "./docs/secGear/使用switchless特性.md" >}})
- [使用secGear工具]({{< relref "./docs/secGear/使用secGear工具.md" >}})
- [接口参考]({{< relref "./docs/secGear/接口参考.md" >}})
- [Kubernetes集群部署指南]({{< relref "./docs/Kubernetes/Kubernetes.md" >}})