29. secure world對smc請求的處理------monitor模式中的處理【轉】

轉自:https://icyshuai.blog.csdn.net/article/details/73118852?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control

 歷經一年多時間的系統整理合補充,《手機安全和可信應用開發指南:TrustZone與OP-TEE技術詳解 》一書得以出版,書中詳細介紹了TEE以及系統安全中的所有內容,全書按照從硬件到軟件,從用戶空間到內核空間的順序對TEE技術詳細闡述,讀者可從用戶空間到TEE內核一步一步瞭解系統安全的所有內容,同時書中也提供了相關的示例代碼,讀者可根據自身實際需求開發TA。目前該書已在天貓、京東、噹噹同步上線,鏈接如下(麻煩書友購書時能給予評論,多謝多謝):

京東購買地址

噹噹購買地址

天貓購買地址

非常感謝在此期間大家的支持以及各位友人的支持和幫助!!!。

爲方便和及時的回覆讀者對書中或者TEE相關的問題的疑惑(每天必看一次),也爲了大家能有一個統一的交流平臺。我搭建了一個簡單的論壇,網址如下:

https://www.huangtengxq.com/discuz/forum.php

關於您的疑問可在“相關技術討論“”中發帖,我會逐一回復。也歡迎大家發帖,一起討論TEE相關的一些有意思的feature。共同交流。同時該論壇中也會添加關於移動端虛擬化的相關技術的板塊,歡迎各位共同交流學習

若覺得書中內容有錯誤的地方,歡迎大家指出,私信或者在博文中留言聯繫方式亦可發郵件至:[email protected],多謝各位了!!!!我會第一時間處理

  

libteec和tee_supplicant調用接口之後最終會調用到OP-TEE驅動來觸發對應的SMC操作。在OP-TEE驅動中觸發SMC操作的方法是調用arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res)來實現,其中在REE端需要傳遞給TEE側的數據被存放在a0~a7中。調用上述函數自後,CPU中的cortex就會切換到monitor模式,進入monitor模式之後首先會去獲取MVBAR寄存器中存放的monitor模式的中斷向量表地址,然後查找monitor模式的中斷向量表,命中smc的處理函數。進入到處理函數之後再根據從REE側帶入的參數判定是進行快速smc處理還是標準的smc處理。關於monitor模式下如何實現normal world到secure world之間的切換過程請參考文章《18. OP-TEE中secur world和non-secure world的切換過程》。在REE端觸發smc請求之後在monitor的處理流程如下圖所示:

  當程序運行到sm_from_nsec的時候就已經完成了normal world與secure world的切換,從該函數開始就進入到了OP-TEE的處理範疇。

1. Monitor模式的中斷向量表中的smc處理函數

  當在REE側觸發了smc請求時,cortex切換到monitor模式並獲取monitor模式的中斷向量表sm_vect_table的地址,該向量表的地址在OP-TEE的啓動的時候會被保存到MVBAR寄存器中。觸發了smc請求之後將會調用向量表中的sm_smc_entry函數來對請求進行處理。sm_smc_entry函數是用匯編編寫的,其內容在以前的文章中有詳細的介紹。如果系統支持ATF,則該部分的處理將會發生在ATF的bl31階段。本文不考慮ATF的情況。

  在sm_smc_entry中對當前SCR寄存器中的NS爲來判定請求是來自於secure world還是normal world。如果請求來自於REE側,則程序會執行smc_from_nsec分支完成SCR中NS的設置並調轉到sm_from_nsec函數繼續執行。

2.判定smc請求類型

  smc請求處理函數執行到sm_from_nsec函數後就會對smc請求的類型進行判定,判定該smc請求時屬於快速smc還是標準的smc請求。該判定是通過判定r0寄存器中存放的數據中的第31個bit的值是1還是0,如果bit31的值是1,則表面該smc請求時快速smc(fast smc),如果該值爲0則是標準smc請求。關於r0參數每個bit的函數請參考文章《25. OP-TEE驅動篇----驅動編譯,加載和初始化(二)》中的最後一個章節。sm_from_nsec函數的內容如下:

 

  1.  
    bool sm_from_nsec(struct sm_ctx *ctx)
  2.  
    {
  3.  
    uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0);
  4.  
     
  5.  
    /* 平臺相關處理 */
  6.  
    if (!sm_platform_handler(ctx))
  7.  
    return false;
  8.  
     
  9.  
    #ifdef CFG_PSCI_ARM32
  10.  
    if (OPTEE_SMC_OWNER_NUM(*nsec_r0) == OPTEE_SMC_OWNER_STANDARD) {
  11.  
    smc_std_handler((struct thread_smc_args *)nsec_r0);
  12.  
    return false; /* Return to non secure state */
  13.  
    }
  14.  
    #endif
  15.  
     
  16.  
    /* 保存non-secure world各種寄存器的值 */
  17.  
    sm_save_modes_regs(&ctx->nsec.mode_regs);
  18.  
     
  19.  
    /* 恢復secure world的寄存器的值 */
  20.  
    sm_restore_modes_regs(&ctx->sec.mode_regs);
  21.  
     
  22.  
    /* 將從驅動傳遞過來的第一個參數r0拷貝到ctx->sec.ro中 */
  23.  
    memcpy(&ctx->sec.r0, nsec_r0, sizeof(uint32_t) * 8);
  24.  
     
  25.  
    /* 判定第一個參數的bit31的值是否爲1 */
  26.  
    if (OPTEE_SMC_IS_FAST_CALL(ctx->sec.r0))
  27.  
    /* Bit 31的值爲1,調用fast smc的thread進行處理 */
  28.  
    ctx->sec.mon_lr = (uint32_t)&thread_vector_table.fast_smc_entry;
  29.  
    else
  30.  
    /* Bit 31的值爲0,調用std smc的thread進行處理 */
  31.  
    ctx->sec.mon_lr = (uint32_t)&thread_vector_table.std_smc_entry;
  32.  
    return true; /* return into secure state */
  33.  
    }

 

3. OP-TEE中的線程向量表----thread_vector_table

 

  在OP-TEE中用於處理各種來自外部或者的monitor模式請求的入口函數都存放在OP-TEE的線程向量表thread_vector_table中。該項量的實現在optee_os/core/arch/arm/kernel/thread_a32.S文件中。其內容如下:

  1.  
    FUNC thread_vector_table , :
  2.  
    UNWIND( .fnstart)
  3.  
    UNWIND( .cantunwind)
  4.  
    b vector_std_smc_entry //OP-TEE中處理標準smc請求
  5.  
    b vector_fast_smc_entry //OP-TEE中處理快速smc
  6.  
    b vector_cpu_on_entry //OP-TEE中處理cpu on操作
  7.  
    b vector_cpu_off_entry //OP-TEE中處理cpu off操作
  8.  
    b vector_cpu_resume_entry //OP-TEE中處理resume操作
  9.  
    b vector_cpu_suspend_entry //OP-TEE中處理cpu suspend操作
  10.  
    b vector_fiq_entry //OP-TEE中處理處理快速中斷操作
  11.  
    b vector_system_off_entry //OP-TEE中處理系統off操作
  12.  
    b vector_system_reset_entry //OP-TEE中處理系統重啓操作
  13.  
    UNWIND( .fnend)
  14.  
    END_FUNC thread_vector_table

  注意該線程向量表與OP-TEE的中斷處理向量表thread_vect_table是不一樣的。thread_vector_table 屬於線程級別,會被monitor模式或者其他中斷處理函數調用到,而thread_vect_table纔是OP-TEE存放在VBAR寄存器中的中斷向量表。當在secure world狀態下產生了FIQ事件時,將會調用中斷向量表thread_vect_table中的FIQ中斷處理函數,然後纔會調用到thread_vector_table中給的vector_fiq_entry來執行FIQ的後續處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章