optee CA/TA flow

在这里插入图片描述

在这里插入图片描述
TEEC_InvokeCommand 为例

CA—normal world EL0

//imx-optee-client\libteec\src\tee_client_api.c
TEEC_InvokeCommandioctl(session->ctx->fd, TEE_IOC_INVOKE, &buf_data)

通过syscall陷入内核态driver

linux driver—normal world EL1

tee_ioctl  // drivers\tee\tee_core.ctee_ioctl_invokectx->teedev->desc->ops->invoke_funcoptee_invoke_func  // drivers\tee\optee\call.c// Does and SMC to OP-TEE in secure world // and handles eventual resulting Remote // Procedure Calls (RPC) from OP-TEE.// Returns return code from secure world, 0 is OKoptee_do_call_with_argoptee->invoke_fn  // get_invoke_funcoptee_smccc_smcarm_smccc_smc__arm_smccc_smcSMCCC SMCCC_SMCsmc #0  //同步异常陷入EL3,执行bl31的中断向量表

其中 ops->invoke_func 在 linux\drivers\tee\optee\core.c 中注册

static const struct tee_driver_ops optee_ops = {.get_version = optee_get_version,.open = optee_open,.release = optee_release,.open_session = optee_open_session,.close_session = optee_close_session,.invoke_func = optee_invoke_func,.cancel_req = optee_cancel_req,.shm_register = optee_shm_register,.shm_unregister = optee_shm_unregister,
};

bl31—EL3

https://blog.csdn.net/orlando19860122/article/details/117034843

// atf\bl31\aarch64\runtime_exceptions.S
sync_exception_aarch64 //从EL1跳转到EL3,即从低到高handle_sync_exceptionsmc_handler64// 根据x0计算出一个runtime service(opteed_smc_handler),然后跳转blr x15// el3_exit 函数最后调用 eret 从 el3 跳到 secure el1// 跳转到optee os的入口 fast_smc_entry、yield_smc_entryb el3_exit

https://blog.csdn.net/yiyueming/article/details/72885273

opteed_smc_handler------Runtime Service
opteed_smc_handler// 保存non sercure world contextcm_el1_sysregs_context_save(NON_SECURE);// Set appropriate entry for SMC.// fast_smc_entry or yield_smc_entrycm_set_elr_el3(SECURE, (uint64_t)&optee_vector_table->fast_smc_entry);cm_set_elr_el3(SECURE, (uint64_t)&optee_vector_table->yield_smc_entry);// 保存 sercure world contextcm_el1_sysregs_context_restore(SECURE)SMC_RET4 // 返回smc_handler64继续执行 b el3_exit

optee os—secure world EL1

std

vector_std_smc_entry  //  core\arch\arm\kernel\thread_optee_smc_a64.Sbl thread_handle_std_smc  // core\arch\arm\kernel\thread_optee_smc.cthread_alloc_and_run__thread_alloc_and_run(a0, a1, a2, a3, a4, a5, 0, 0,thread_std_smc_entry)//core\arch\arm\kernel\thread_optee_smc_a64.Sthread_std_smc_entry__thread_std_smc_entrystd_smc_entrycall_entry_stdtee_entry_std__tee_entry_std // core\tee\entry_std.ccase OPTEE_MSG_CMD_INVOKE_COMMAND:entry_invoke_command(arg, num_params)tee_ta_invoke_commandts_ctx->ops->enter_invoke_cmd(&sess->ts_sess, cmd)//core\kernel\user_ta.cuser_ta_enter_invoke_cmduser_ta_enter//sercure world os space->user space//返回到user space中 参数 entry_functhread_enter_user_modesmc #0

uta—secure world EL0

thread_enter_user_mode 从 sercure world os space(EL1、optee os)返回到sercure world user space(EL0、uta),返回地址是该函数的入参entry_func,TA_InvokeCommandEntryPoint,去执行uta的函数。执行完返回,最后调用 smc #0,触发异常,跳转到EL3。

bl31—EL3

异常进入EL3以后,我们知道之前退出EL3的时候sp_el3指向的是secure context,因此再进入EL3了,用到sp_el3就是指向secure context的。前面的执行流程相同,只是到了opteed_smc_handler函数,跳过了前面caller is secure的分支,因为我们是从secure的环境进入的,直接到了后面 switch(smc_fid) 的逻辑。

// atf\bl31\aarch64\runtime_exceptions.S
sync_exception_aarch64 //从EL1跳转到EL3,即从低到高handle_sync_exceptionsmc_handler64// 根据x0计算出一个runtime service(opteed_smc_handler),然后跳转blr x15// el3_exit 函数最后调用 eret 从 el3 跳到 secure el1b el3_exit

opteed_smc_handler------Runtime Service

opteed_smc_handler// Returning from OPTEEswitch (smc_fid) {//...case TEESMC_OPTEED_RETURN_CALL_DONE:assert(handle == cm_get_context(SECURE));cm_el1_sysregs_context_save(SECURE);/* Get a reference to the non-secure context */ns_cpu_context = cm_get_context(NON_SECURE);assert(ns_cpu_context);/* Restore non-secure state */cm_el1_sysregs_context_restore(NON_SECURE);cm_set_next_eret_context(NON_SECURE);//返回到b el3_exit,然后通过eret返回到REE侧的EL1SMC_RET4(ns_cpu_context, x1, x2, x3, x4);

由于从secure el1返回的时候,x0带的参数是TEESMC_OPTEED_RETURN_CALL_DONE,即smc_fid = TEESMC_OPTEED_RETURN_CALL_DONE。所以我们直接看这个分支的处理函数。

  • 首先保存了secure el1的sys寄存器,用于下次secure调用
  • 获取non-secure的context,这个在之前是保过的
    然后恢复non-secure el1的sys寄存器
  • 设置non-secure的context,用于下次non-secure的调用,注意这里会配置sp_el3寄存器,指向了non-secure context,也就是为什么在最开始,我们从non-secure调用下来,默认使用的是non-secure context,就是每次使用完毕以后,在这里都会设置一下,供下次使用。
  • 设置了non-secure context的前4个变量a0~a3为x1, x2, x3, x4。其实就是thread_handle_fast_smc调用结束后的x0, x1, x2, x3。现在算是把原本的值填回到了本来的位置。然后return返回。

返回后的位置是smc_handler64最后一行,最后smc_handler64通过el3_exit返回到了REE侧的EL1。后面列一下SMC中断退出后硬件做的一些事情的伪代码。可以看到硬件从spsr_el3恢复了PSTATE,说明了此时unmask了fiq和irq。

linux driver—normal world EL1

又回到了REE侧的EL1,我们上次走到这里还是只调用了一个smc #0,我们继续看arm_smccc_smc在调用smc以后的逻辑,即SMCCC的宏:

	.macro SMCCC instr\instr	#0  /* 执行instr参数的内容,即执行smc切换 */ldr	x4, [sp]  /* 切换返回,出栈操作,恢复现场 */stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]ldr	x4, [sp, #8]cbz	x4, 1f /* no quirk structure */ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6b.ne	1fstr	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
1:	ret  //返回到 el0 继续执行.endm

根据SMC CALL CONVENTION规则,参数前8个是通过x0x7传递,第9个通过栈传递,现在我们看到的sp就是保存返回结果的结构体地址。我们从前面的分析知道,目前,OPTEE返回的结果保存在x0x3的寄存器里,所以我们看到后的操作就是把x0~x3的值写到保存结果的结构体,即struct arm_smccc_res res;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/472917.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣题目训练(11)

2024年2月4日力扣题目训练 2024年2月4日力扣题目训练455. 分发饼干459. 重复的子字符串463. 岛屿的周长146. LRU 缓存147. 对链表进行插入排序76. 最小覆盖子串 2024年2月4日力扣题目训练 2024年2月4日第十一天编程训练,今天主要是进行一些题训练,包括简…

VMware Workstation 17.0 虚拟机安装MS-DOS 7.1完整详细步骤图文教程

VMware Workstation 17.0 虚拟机安装MS-DOS 7.1完整详细步骤图文教程 一、配置MS-DOS虚拟机机器环境二、安装MS-DOS磁盘操作系统 一、配置MS-DOS虚拟机机器环境 1.打开VMware Workstation Pro 2.新建虚拟机 3.建议选择【典型】,之后点击【下一步】 关于【自定义…

分省年度数据集(1990-2021年)

一、数据介绍 数据名称:分省年度数据集(1990-2021年) 数据来源:国家统计局-分省年度数据 数据范围:1990-2021年,包括31个省份 指标数量 :2981个指标 数据整理:自主整理 更新时…

简单的edge浏览器插件开发记录

今天在浏览某些网页的时候,我想要屏蔽掉某些信息或者修改网页中的文本的颜色、背景等等。于是在浏览器的控制台中直接输入JavaScript操作dom完成了我想要的功能。但是每次在网页之间跳转该功能都会消失,我需要反复复制粘贴js脚本,无法实现自动…

【数据分享】2001~2020年青藏高原植被净初级生产力数据集

各位同学们好,今天和大伙儿分享的是2001~2020年青藏高原植被净初级生产力数据集。如果大家有下载处理数据等方面的问题,您可以私信或评论。 朱军涛. (2022). 青藏高原植被净初级生产力数据集(2001-2020). 国家青藏高原数据中心. …

Rust 学习笔记 - Hello world

前言 本文将讲解如何完成一个 Rust 项目的开发流程,从编写 “Hello, World!” 开始,到使用 Cargo 管理和运行项目。 编写 Hello world 开始一个新项目很简单,首先,创建一个包含 main.rs 文件的 hello_world 文件夹,…

错误处理 ssh登陆提示:server unexpectedly closed network connection

干了一天的活,因为对etc做权限操作,导致ssh不能连接,差点奔溃 记这次处理经验 因修改/etc/ssh权限导致的ssh不能连接异常解决方法 现象: $ssh XXX192.168.5.21 出现以下问题 Read from socket failed: Connectionreset by peer …

在Visual Studio中搭建Dynamo Python开发环境,效率飞一般的增长

最近在学习Dynamo中Python Script的用法,发现这个东西用起来太不友好了,不支持自动缩进,不支持自动填充和提示。用过Visual Studio做二开的都知道,在引用了Revit api以后,就可以自动填充和提示了。 本来英语就不好&am…

图像识别基础之模板匹配

principle 图像匹配 本质:图像的相似度很高(矩阵的相似度很高) code /*\brief 我的图像匹配函数,获取差方和均值最小的矩阵作为结果\param srcPicFile:用以匹配的图像文件\param templatePicFile:模板图像文件\param destPicFile:输出的检测结果文件…

一周学会Django5 Python Web开发-项目配置settings.py文件-数据库配置

锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计17条视频,包括:2024版 Django5 Python we…

【Linux内核】从0开始入门Linux Kernel源码

🌈 博客个人主页:Chris在Coding 🎥 本文所属专栏:[Linux内核] ❤️ 前置学习专栏:[Linux学习]从0到1 ⏰ 我们仍在旅途 ​ 目录 …

Qt:Qt3个窗口类的区别、VS与QT项目转换

一、Qt3个窗口类的区别 QMainWindow:包含菜单栏、工具栏、状态栏 QWidget:普通的一个窗口,什么也不包括 QDialog:对话框,常用来做登录窗口、弹出窗口(例如设置页面) QDialog实现简易登录界面…