请问如果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)的一些资源呢?
我对于这块还只能算是初学者,提前谢谢大家!
在ethanzhang的基础上在补充一下。
每个EL, 还有同一个EL(比如EL1)的secure和non-secue下都有自己TTBR, MMU和Cache的配置。
kernel代码在执行SMC切换到EL3, ARM trusted firmware里面后,会使用自己的MMU,TTBR0_EL3的配置。
若涉及到memory访问,需要传递物理地址。
有个代码的例子,供参考:
Linux kernel传递指针给ARM trusted firmware的时候,是物理地址。 比如PSCI CPU ON的代码:
arch/arm64/kernel/psci.c
static int cpu_psci_cpu_boot(unsigned int cpu)
{
int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry));
......
}
不了解你想在EL3访问non-secure EL1的什么资源? 假如是memory的话,只要传递PA就可以了,当然EL3的MMU要配置好。
谢谢你的回复,
我是想在每次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的回答是正解