Linaro RMM 代码初步阅读
本文最后更新于 117 天前,其中的信息可能已经有所发展或是发生改变。

RMM,即 Realm 管理监视器。管理 Realm 机密虚拟机,同时做为了机密虚拟机和虚拟机管理者之间沟通的桥梁。

RMM 代码获取方法:

mkdir cca-v4
cd cca-v4
repo init -u https://git.codelinaro.org/linaro/dcap/op-tee-4.2.0/manifest.git -b cca/v4 -m sbsa_cca.xml
repo sync -j8 --no-clone-bundle

RMM 代码框架

cca-v4 的根目录下,可以看到 rmm 目录,为 RMM 项目的主目录。目录结构如下:

|- cmake
|- configs
|- docs
|- drivers
|- ext
|- lib
|- plat
|- runtime
|- toolchain
|- tools

lib 文件夹中有相关的库功能实现,例如 GIC 的实现。runtime 文件夹中就是 RMM 的运行时代码。我们再看看 runtime 文件目录:

|- core
|- include
|- rmi
|- rsi
|- tests
  • core:一些……
  • include:相关头文件
  • rmirmi 接口相关代码的实现
  • rsirsi 接口相关代码的实现
  • tests:一些测试文件

我们重点关注 core / rmi / rsi 文件夹中的代码。

REC_ENTER

从非安全环境 (NS) 中进入 Realm,需要调用 RMI_REC_ENTER。搜索 REC_ENTER 关键字,得到了以下内容:

Pasted image 20241228175950

第一条搜索内容就很有意义。我们在 core/handler.c 代码中找到了 smc_handler 结构体。该结构体定义了绝大多数 RMI 接口功能的处理函数。REC_ENTER 的处理函数是 smc_rec_enter

rmi/run.c 文件中,我们找到了 smc_rec_enter 的原型。该函数体现出了 REC 进入和退出的一个完整周期:

  • 清空 RecExit 结构体。
  • 获取 RecEnter 中的信息。
  • 检查 Realm 的状态。
  • 检查 GIC 的状态,并将 GIC 的状态拷贝到 RecEnter 中。
  • 检查之前的处理异常时模拟的结果。
  • 调用 rec_run_loop 函数。
  • 此时 REC 已经退出,将 GIC 信息拷贝到 RecExit 中。

rec_run_loop 是一个关键点。在此之前,是在检查进入 REC 前的相关条件是否符合要求;在此之后,就是保存 GIC 的相关信息。我们再 core/run.c 文件中找到了 rec_run_loop 的原型。该函数涉及到 REC 上下文相关的处理:

  • 保存 NS 的上下文。

  • 恢复 Realm 的上下文。

  • 进行一些 attest 相关操作。

  • 进入一个循环体。

    • 检查时钟状态。如果计时器时间达到,就直接退出循环体。
    • 激活 REC 相关事件。
    • 保存 RMM 的 cptr_el2 寄存器,恢复 Realm 的 cptr_el2 寄存器。
    • 恢复 Realm 的密钥。
    • 调用 run_realm,参数是 REC 的通用寄存器堆。
    • 保存 Realm 的密钥。
    • 恢复 RMM 的密钥。
    • 保存 Realm 的 cptr_el2 寄存器,恢复 RMM 的 cptr_el2 寄存器。
    • 检查 Realm 退出的原因,决定是否继续执行循环体。
  • 反馈 Realm 的时钟状态。

  • 保存 Realm 的上下文。

  • 恢复 NS 的上下文。

几个比较重要的点,时钟的检查,Realm 的上下文的保存与恢复,run_realm 函数以及检查 Realm 退出原因。

Realm 的上下文

RMM 分别调用 save_realm_state 以及 restore_realm_state 函数保存和恢复 Realm 的上下文。两个函数均在 core/run.c 文件中。我们以 save_realm_state 为例子,会涉及到以下过程:

  • 调用 save_sysreg_state 保存系统寄存器至 REC 中。
  • elr_el2 的值保存到 REC 的 PC 中。
  • spsr_el2 的值保存到 REC 的 pstate 中。
  • 保存 GIC 信息到 REC 中。
  • 对 PMU 一些内容进行处理。

此处比较关键的内容就是 save_sysreg_state 函数。同样也在 core/run.c 文件中,找到了这个函数。函数内容基本都是赋值语句,将读取到的 sysreg 的值存储到相应的 REC 寄存器中。这些寄存器就有我们比较关注的寄存器,例如 ttbrvbar 等。这个函数可以证明,整个 REC 就一套 sysreg。


对于时钟和 Realm 退出检查的内容,会在后面的博客讲述。

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇