Baron:程序运行过程中突然打开MMU会怎么样?
本文作者的ARM安全架构训练营火热报名中,和作者一起快速学习ARM架构安全和安全业务设计,安全启动、DRM等实战案例线上演示,实战指导:阅码场训练营:ARM安全架构之Trustzone-TEE实战。报名咨询客服(小月微信:linuxer2016)。
作者简介:
Baron (csdn:代码改变世界ctw),九年手机安全/SOC底层安全开发经验。擅长trustzone/tee安全产品的设计和开发
(注:说明本文的介绍都是基于armv8-aarch64或armv9硬件架构)
在mmu未开启阶段,PC操作的都是物理地址执行程序,这样看起来一切正常,没啥问题。
例如:取指(到物理地址0x4000处取指)、译码、执行 取指(物理地址0x4004处取指)、译码、执行 取指(物理地址0x4008处取指)、译码、执行 取指(物理地址0x400C处取指)、译码、执行
但是呢,假如程序在执行的过程中,你突然打开了MMU,那么会发生什么呢?比如在前面的示例中,就会出现,程序本来执行在0X4000、0x4004处好好的,而0x4004切好是enable_mmu指令,那么接下来PC将取值0x4008处地址的指令,由于此时MMU已经被打开了,那么0x4008会被当作虚拟地址,经过MMU翻译...
经过MMU,那么就可能出现了两种问题:一是虚拟地址0x4008所对应的页表没有建立,此时会产生prefetch abort;二是虚拟地址0x4008所对应的页表已经建立了(例如指向物理0x9004处),那么此时cpu期望访问物理地址0x4008处的,就被突然变成了访问物理地址0x9004处了。
取指(到到物理地址0x4000处取指)、译码、执行 取指(物理地址0x4004处取指)、译码、执行 -- 这条指令是开启MMU取指(到虚拟地址0x4008处取指,经MMU单元后,要么是invalid,要么是0x9004)、译码、执行 ......
为了解决上述描述的问题,下面给出了两种解决方案:第一种方案:在开启MMU之前,我先对正在执行的这一小块代码建立个页表(一一映射),那么此时的逻辑就变成了:
取指(到到物理地址0x4000处取指)、译码、执行 取指(物理地址0x4004处取指)、译码、执行 -- 这条指令是开启MMU取指(到虚拟地址0x4008处取指,经MMU单元后,物理地址依然是是0x4008)、译码、执行 -- 程序没有跑飞......
第二种方案:在开启MMU之前,我确实建立个页表(不是一一映射哦,这是正常业务的页表),此时的逻辑如下:
取指(到到物理地址0x4000处取指)、译码、执行 取指(物理地址0x4004处取指)、译码、执行 -- 这条指令是开启MMU取指,到虚拟地址0x4008处取指,经MMU单元时在页表是找不到0x4008这个虚拟地址的(因为没做map),所以会产生prefetch abort异常、而在异常代码ERET返回时,正好返回到0xXXXX地址处,该地址是虚拟地址,正好MAP到0x4008物理地址,程序得到继续执行,译码、执行 -- 程序很顺利哦......
如果看到此处,您没有看懂,没关系,请看下列代码示例:
程序在(1)处将 mmu_on_addr
链接地址(虚拟地址)写入到了X30寄存器中
程序在(2)处enable MMU,此时下一条指令取指,将被当作成虚拟地址,经过MMU翻译,而对应的页表中自然是没有这个地址(物理地址被当作成的虚拟地址),所以此时将产生sync abort...
程序在(3)处不会被执行,因为上面已经sync abort了
跳转到sync abort后,代码如下方所示,什么都没干,直接ret返回了。
vector_entry sync_exception_sp_elx
ret
ret
指令返回的,PC自然是自动指向X30地址处,即 mmu_on_addr
链接地址(虚拟地址),程序继续跑,一切步入正常流程...
精华文章:【精华】Linux阅码场原创精华文章汇总
阅码场付费会员专业交流群
会员招募:各专业群会员费为88元/季度,权益包含群内提问,线下活动8折,全年不定期群技术分享(普通用户直播免费,分享后每次点播价为19元/次),有意加入请私信客服小月(小月微信号:linuxer2016)
专业群介绍:
彭伟林-阅码场内核性能与稳定性本群定位内核性能与稳定性技术交流,覆盖云/网/车/机/芯领域资深内核专家,由阅码场资深讲师彭伟林主持。甄建勇-性能优化与体系结构
本群定位Perf、cache和CPU架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师甄建勇主持。
李春良-Xenomai与实时优化
本群定位Xenomai与实时优化技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师李春良和彭伟林共同主持。
周贺贺-Tee和ARM架构
本群定位Tee和ARM架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师周贺贺主持。
谢欢-Linux tracers
本群定位Linux tracers技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师谢欢主持。
✦
✦