zoukankan      html  css  js  c++  java
  • 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。共同交流。同时该论坛中也会添加关于移动端虚拟化的相关技术的板块,欢迎各位共同交流学习

    若觉得书中内容有错误的地方,欢迎大家指出,私信或者在博文中留言联系方式亦可发邮件至:shuaifengyun@126.com,多谢各位了!!!!我会第一时间处理

      

    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的后续处理。

  • 相关阅读:
    设置圆形头型并且可以点击
    不可忽略的知识点
    【Java基础】03_Java常用API
    常用键盘功能键和快捷键以及DOS命令
    【Excel 2013 数据透视表 学习】一、创建数据透视表
    【Java基础】05_异常&File
    【Java基础】04_集合框架
    【设计模式之禅】第2章 里氏替换原则
    【设计模式之禅】第1章 单一职责原则
    Eclipse中快捷键的使用
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/14212123.html
Copyright © 2011-2022 走看看