Closed equation314 closed 5 years ago
可以复现
在trap handler里把四级页表打出来,没看出问题 (感觉是玄学)
发生此问题的主要原因是:上下文切换到内核线程时,往 TLB 中加入了 gloabl 属性的某项,导致切换为用户线程后访问同一虚拟地址时,根据 TLB 中错误的该项,将该虚拟地址映射为了错误的物理地址。
具体地,对于位于低地址空间的 0x8000
的虚拟地址,内核线程的页表会将其映射为相同的物理地址 0x8000
。当上下文切换到内核线程时,由于某些原因(可能是对 [0~0x20000]
这 2MB 大页内的地址进行了访存,暂未查明)将 0x8000
到 0x8000
的映射加入了 TLB,并且属性为 global。切换为用户线程后,用户程序对 0x8000
页内的某一虚拟地址进行了取指,此时虽有 ASID 机制,但 TLB 中的那项属性为 global,仍然可以匹配成功,于是仍将该虚拟页映射到了 0x8000
的错误物理页帧,从而取出了错误的数据,将其作为了非法的指令,导致了 page fault。
d56a88947e0d3fb7531dcca572d835a2862bd690 的解决方法:将内核线程的 ttbr0_el1
设为空,使得内核线程无法访问低地址空间。
Commit: e63f11d19904f42835b97ced94ae7ccada28a78d Build command:
Serial port log (with some debug info):