TLB中ASID和nG bit的关系

贴一篇当年关于TLB的笔记。

TLB是硬件上的一个cache,用于提升访问页表(这里应该是二级页表)的速度。MMU在将虚拟地址转换成物理地址时首先去TLB中找合适entry,如果能找到,则立即返回物理地址;如果TLB中找不到,则需访问Memory中的页表,且会加载相关entry到TLB中,以备下次MMU转换使用。
这个过程中存在一个问题,因为process的页表具有私密性,且kernel process和user process也需要做隔离。所以TLB中的entry需要保证只有本process可以访问。一个最简单的办法来实现这种屏蔽就是在做context switch时将TLB中的内容全部刷掉重新载入新process的entry,但是这样做效率会降低。为减少这部分消耗时间,ARM实现了在TLB中同时存放多个process页表的功能。
实现这个功能的硬件基础是,nG bit和ASID。硬件页表中有一个bit来指明当前的entry是global(nG=0,所有process都可以访问)还是non-global(nG=1,only本process允许访问)。如果是global类型,则TLB中不会tag ASID;如果是non-global类型,则TLB会tag上ASID,且MMU在TLB中查询时需要判断这个ASID和当前进程的ASID是否一致,只有一致才证明这条entry当前process有权限访问。
ASID的赋值方法参考代码。可以发现内核线程fork()时是不会初始化ASID这个值的,且低端内存在page初始化时的flag中nG=0,这表明内核空间是global的。而用户线程在fork()过程中会初始化asid = 0,且在做context switch,调度fork()的process进入RUNNING状态时会将这个asid赋为正式计算出的值,并且硬件页表中的nG有机会赋值1。
详细可以参考如下介绍:
1. http://stackoverflow.com/questions/17590146/how-to-deal-the-circumstance-of-asids-are-used-up-in-linux-kernel
2. http://blog.tek-life.com/%E8%AE%A4%E8%AF%86asid/

猜你喜欢

转载自blog.csdn.net/rockrockwu/article/details/81090883