构建动态TCS页

如果支持EDMM,我们就可以动态生产TCS,因此一开始我们可能只给一部分TCS分配好空间,还有一部分动态TCS并未分配空间,这些动态TCS按需生成。

这个产生TCS的过程是需要Enclave内外共同合作完成,Enclave内部完成【ECMD_MKTCS】任务,中途会调用OCALL到Enclave外部执行【make_tcs】,其中会发信令【SGX_IOC_ENCLAVE_MKTCS】给SGX驱动,让SGX驱动构建一个TCS页。因为需要用到ENCLS这个Ring0指令,所以需要由SGX驱动完成。

那么下面就要介绍如何动态生成这些动态TCS。

构建动态TCS的API

此时位于uRTS,试图构建Enclave。

sgx_status_t CTrustThreadPool::new_thread()
{
    ...
    void **ocalls = octbl->ocall;
    *ocalls = reinterpret_cast<void*>(make_tcs);
    ...
    ret = (sgx_status_t)do_ecall(ECMD_MKTCS, octbl, &ms1, m_utility_thread);
    ...
}

注册一下【make_tcs】这个OCALL函数。然后进入Enclave,【ECMD_MKTCS】。

进入Enclave来构建动态TCS

进入Enclave的流程:【do_ecall】->【enter_enclave/__morestack(uRTS)】->【enclave_entry】->【enter_enclave(tRTS)】

我们这次是【ECMD_MKTCS】任务,因此紧接着【enter_enclave(tRTS)】走的是【do_ecall_add_thread】函数。

sgx_status_t do_ecall_add_thread(void *ms){
    ...
    if(!is_utility_thread())
    ...
    status = do_save_tcs(ptcs);
    ...
    status = do_add_thread(ptcs);
}

确保当前线程是通用线程(Utility Thread)

先通过gs寄存器(64位下,32位使用fs寄存器)找到每个Enclave线程自己的数据——一个thread_data_t对象。

typedef struct _thread_data_t
{
    sys_word_t  self_addr;
    sys_word_t  last_sp;            /* set by urts, relative to TCS */
    sys_word_t  stack_base_addr;    /* set by urts, relative to TCS */
    sys_word_t  stack_limit_addr;   /* set by urts, relative to TCS */
    sys_word_t  first_ssa_gpr;      /* set by urts, relative to TCS */
    sys_word_t  stack_guard;        /* GCC expects start_guard at 0x14 on x86 and 0x28 on x64 */

    sys_word_t  flags;
    sys_word_t  xsave_size;         /* in bytes (se_ptrace.c needs to know its offset).*/
    sys_word_t  last_error;         /* init to be 0. Used by trts. */

#ifdef TD_SUPPORT_MULTI_PLATFORM
    sys_word_t  m_next;             /* next TD used by trusted thread library (of type "struct _thread_data *") */
#else
    struct _thread_data_t *m_next;
#endif
    sys_word_t  tls_addr;           /* points to TLS pages */
    sys_word_t  tls_array;          /* points to TD.tls_addr relative to TCS */
#ifdef TD_SUPPORT_MULTI_PLATFORM
    sys_word_t  exception_flag;     /* mark how many exceptions are being handled */
#else
    intptr_t    exception_flag;
#endif
    sys_word_t  cxx_thread_info[6];
    sys_word_t  stack_commit_addr;
} thread_data_t;

这里面记录了线程相关的很多信息。其中一个Flags中的Bit信息是说明当前线程是不是通用线程。因为在支持EDMM的情况下,我们只通过这个通用线程来对动态TCS进行分配操作,此外所有动态结构也都依赖于这个通用线程来完成,通用线程其中的一个目的就是来处理这种动态结构。之前执行的【ECMD_INIT_ENCLAVE】任务,在支持EDMM情况下,也是由通用线程来完成。

Enclave内部记录下TCS地址

status = do_save_tcs(ptcs);

tRTS内保存起来这个TCS的地址。当前第一次存这个TCS的地址时,会构造一个随机数值的全局的TCS Cookie【g_tcs_cookie】,将TCS的地址用TCS Cookie异或加密,并加入【g_tcs_node】链表。

开始构建TCS

// Create a thread dynamically.
// It will add necessary pages and transform one of them into type TCS.
sgx_status_t do_add_thread(void *ptcs){
    ...
    if ( 0 != check_dynamic_range((void *)tcs, 1, &offset, NULL))
    ...
    // check if the tcs provided exactly matches the one in signtool
    ...
    // adding page for all the dynamic entries
    ...
    //Copy and initialize TCS
    ...
    //Adjust the tcs fields
    ...
    //OCALL for MKTCS
    ...
    //EACCEPT for MKTCS
    ...
}

上面将TCS地址挂载到了一个全局变量。这里是对这个TCS进行赋予内容。首先检查是不是处于元数据指定的动态布局中,因为我们这里其实就是动态的构建TCS,并且此时主要是因为已有的TCS数量达不到最小值。然后检查TCS所在的位置是不是和【LAYOUT_ID_TCS_DYN】布局所在的位置一致。然后接受EECCEPT之前动态线程布局的修改,用g_global_data保存的TCS模板初始化这个TCS,并进行简单基址调整。

退出Enclave,让SGX驱动构建TCS页

这时,就需要先从Enclave出去,执行OCALL Table里的【make_tcs】函数。发信令【SGX_IOC_ENCLAVE_MKTCS】给SGX驱动,让其完成TCS页的构建。

SGX驱动的操作如下。

/**
 * sgx_ioc_page_to_tcs() - Pages defined in range are switched to TCS.
 * These pages should be of type REG.
 * eaccept needs to be invoked after return.
 * @arg range address of pages to be switched
 */
long sgx_ioc_page_to_tcs(struct file *filep, unsigned int cmd, unsigned long arg)

回到Enclave,接受SGX驱动对TCS页的构建操作

紧接着就又回到Enclave。【ECMD_ORET】代表这次进入Enclave是之前曾退出过Enclave。回到Enclave,接着之前的Enclave内的流程——EACCEPT接受SGX驱动对TCS页的构建。到此,构建TCS页的任务就结束了。

构建TCS页结束,回到【CTrustThreadPool::new_thread】进行TCS相关列表维护

如果TCS构建成功,那么就把这个TCS封装成的CTrustThread对象加入到“用于调试的TCS信息列表”,并加入到空闲可用线程列表中【CTrustThreadPool::m_free_thread_vector】。将它从未分配空间TCS列表【CTrustThreadPool::m_unallocated_threads】中删除,因为它现在已经被分配空间了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值