请问如果EL1里面运行的内核调用了一个SMC指令(通过SMC去请求secure world的服务),然后这个调用被运行在EL3的ARM-Trusted-Firmware(EL3运行的相当于monitor)接收到了,这个时候EL3能否按照EL1的地址映射方式去访问EL1里面的虚拟内存?(在访问的时候还没有切换到secure os的context)
比如,EL1里面运行的是linux内核,linux内核空间的虚拟地址为addr1(比如sys_call_table),然后我试图在EL3里面直接通过
memcpy(dest, addr1_of_sys_call_table, size);
这种方式来访问,但是导致系统卡住了,也没有提示访问错误之类的。
我是在smc_handler一开始就访问的,所以应该不会存在什么context破坏的问题(TTBR0_EL1, TTBR0_EL3我都没有动过),除非是smc调用本身会造成一些context的转换,又或者是因为EL3级别使用的是TTBR0_EL3而不是TTBR0_EL1? 如果是这样的话,可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table吗?
如果不可以的话,那请问有什么办法在EL3(monitor)级别或者secure-EL1(secure os)级别访问到EL1(normal world)的一些资源呢?
我对于这块还只能算是初学者,提前谢谢大家!
谢谢你的回复,
我是想在每次non-secure EL1执行一个smc调用的时候,在EL3里面的smc_handler里面去访问EL1里面一些关键内存的值,比如在转换context之前去访问一下sys_call_table的内容。
是的,手册上说它们使用的是不同的mmu,那是不可以强行指定使用EL1的MMU来按照normal world的方式来访问内存吗?
不过你说传递的是物理地址的话,这确实可以说的通了,但是我并没有使用到SMC调用传递的物理地址,而是直接指定的立即数当作地址,这种情况下不是应该会被当作虚拟地址吗。另外请问一下你说的,arm-tf使用自己的MMU, 配置TTBR0_EL3,但是我好像没有在代码里面看有关于内存管理的部分,,不知道是不是我看漏了。
如果是传递的物理地址的话,请问有没有办法让它按照EL1的方式去访问呢?
我在想,如果跨EL不可以共享页的话,那么Non-secure EL1和Secure EL1是否可以设置对方的页表并且按照对方的虚拟地址映射方式去访问?
另外顺便请问一下,有没有哪个寄存器可以让Non-secure EL1对于TTBR\SCTLR这些寄存器的访问,统统给trap到EL3来? 我看armv8的手册都是说可以trap到EL2, 但是好像没有那个寄存器可以给trap到EL3来。
原来是我搜索文档的关键词不对,,,现在找到几个可以trap的寄存器了
请问如果EL1里面运行的内核调用了一个SMC指令(通过SMC去请求secure world的服务),然后这个调用被运行在EL3的ARM-Trusted-Firmware(EL3运行的相当于monitor)接收到了,这个时候 EL3能否按照EL1的地址映射方式去访问EL1里面的 虚拟内存?(在访问的时候还没有切换到secure os的context)
不可以,EL1和EL3使用各自的MMU表
可以将addr1转化为物理地址,作为参数传递给EL3,EL3再将该地址映射到自己的MMU表中就可以访问了
我 是在smc_handler一开始就访问的,所以应该不会存在什么context破坏的问题(TTBR0_EL1, TTBR0_EL3我都没有动过),除非是smc调用本身会造成一些context的转换,又或者是因为EL3级别使用的是TTBR0_EL3而不是 TTBR0_EL1? 如果是这样的话,可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table吗?
不可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table,你在EL3中的代码和变量就访问不了了,程序就死掉了
传递物理地址,再将物理地址隐射到对应的MMU表
Yuping Luo的回答是正解