使用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 _cc_sl_config_t {	
	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;
} 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_sizeswitchless调用任务池的大小,实际可容纳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_numswitchless函数支持的最大参数个数,该字段仅在ARM平台生效,SGX平台无此限制。
规格:
ARM:最大值:16;最小值:0

switchless开发流程

这里给出使用 switchless 特性开发一个 C 语言程序 switchless 的例子,方便用户理解使用 switchless 开发应用程序。

基于secGear API开发应用的具体流程请参考开发secGear应用程序.md

  1. 编写 EDL(Enclave Definition Language)文件

    switchless 函数需添加'transition_using_threads'标识。

     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 是安全侧加载动态库,配置如例子中所示。

     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

    4.1 编写 main.c

    使用 cc_enclave_create 创建安全区 enclave 上下文时,需在 features 参数中传入 switchless 特性配置。使能 switchless 特性的主要工作有:创建任务池,大小由配置中的 switchless_call_pool_size 决定;根据 num_uworkers / num_tworkers 创建 Untrust / Trust 工作线程池等。

     #include <stdio.h>
     #include <unistd.h>
     #include <linux/limits.h>
     #include <sys/time.h>
     #include <string.h>
     #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;
     }
    

    4.2 编写非安全侧 CMakeLists.txt

     # 设置编译环境变量
     #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 目录

    5.1 编写安全侧代码 enclave.c

     #include <stdio.h>
     #include <string.h>
     #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;
     }
    

    5.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调用,不会存在问题。

文档捉虫

“有虫”文档片段

问题描述

提交类型 issue
有点复杂...
找人问问吧。
PR
小问题,全程线上修改...
一键搞定!
问题类型
规范和低错类

● 错别字或拼写错误;标点符号使用错误;

● 链接错误、空单元格、格式错误;

● 英文中包含中文字符;

● 界面和描述不一致,但不影响操作;

● 表述不通顺,但不影响理解;

● 版本号不匹配:如软件包名称、界面版本号;

易用性

● 关键步骤错误或缺失,无法指导用户完成任务;

● 缺少必要的前提条件、注意事项等;

● 图形、表格、文字等晦涩难懂;

● 逻辑不清晰,该分类、分项、分步骤的没有给出;

正确性

● 技术原理、功能、规格等描述和软件不一致,存在错误;

● 原理图、架构图等存在错误;

● 命令、命令参数等错误;

● 代码片段错误;

● 命令无法完成对应功能;

● 界面错误,无法指导操作;

风险提示

● 对重要数据或系统存在风险的操作,缺少安全提示;

内容合规

● 违反法律法规,涉及政治、领土主权等敏感词;

● 内容侵权;

您对文档的总体满意度

非常不满意
非常满意
提交
根据您的反馈,会自动生成issue模板。您只需点击按钮,创建issue即可。